WorkerClient
درخواست و پاسخ روی یک Web Worker. کارگرِ خام تنها «فرستادن پیام» و «گرفتن پیام» را میشناسد: دو کار را همزمان بفرستید، دو پیام برمیگردد و راهی نیست بدانید کدام از آنِ کدام است. WorkerClient بر هر درخواست شناسهای میکوبد و هر پاسخ را به Promiseِ خودش میرساند.
API
new WorkerClient(options)
| پارامتر | توضیح | نوع | پیشفرض |
|---|---|---|---|
create | اینکه کارگر چگونه ساخته شود | () => Worker | الزامی |
isProgress | آیا این پیام پیشرفت است؟ (درخواست را تعیین تکلیف نمیکند) | (res) => boolean | res.type === 'progress' |
getProgress | محتوای پیشرفت را بیرون میکشد | (res) => Progress | res.progress |
isError | آیا این پیام خطاست؟ | (res) => boolean | res.type === 'error' |
getErrorMessage | متن خطا | (res) => string | res.message |
timeout | مهلت هر درخواست (میلیثانیه)؛ تنها همان درخواست را رد میکند | number | ندارد |
| عضو | توضیح |
|---|---|
send(request, onProgress?, transfer?) | یک درخواست میفرستد و چشمبهراه پاسخش میماند |
dispose() | کارگر را تمام میکند و هر چه در جریان است رد میکند |
active | اینکه کارگر ساخته شده است یا نه |
pendingCount | شمار درخواستهای در جریان |
serveWorker(handler, options?) — سمت کارگر
همتایی که درون کارگر میدود. از هر درخواست operationId را میخواند، چشمبهراه رسیدگیکنندهٔ شما میماند و پاسخ را با همان شناسه پس میفرستد.
| پارامتر | توضیح | نوع |
|---|---|---|
handler | (request, { progress }) => Response | Promise<Response> | Function |
options.scope | جایی که گوش میدهد. پیشفرض self است؛ برای یک درگاه یا آزمون آن را عوض کنید | object |
options.resultType | مقدار type پاسخ، وقتی رسیدگیکننده چیزی جز شیء برگرداند. پیشفرض 'result' | string |
تابعی به نام stop برمیگرداند که شنونده را برمیدارد.
نمونه
js
import { WorkerClient } from 'ranuts';
const client = new WorkerClient({
create: () => new Worker(new URL('./nlp.worker.ts', import.meta.url), { type: 'module' }),
});
await client.send({ type: 'load', modelId }, (p) => renderProgress(p.progress));
const { scores } = await client.send({ type: 'classify', lines });
client.dispose();و سمت کارگر:
js
// nlp.worker.ts
import { serveWorker } from 'ranuts';
serveWorker(async (request, { progress }) => {
if (request.type === 'load') {
const device = await loadModel(request.modelId, (p) => progress(p));
return { type: 'loaded', device };
}
return { type: 'result', scores: await classify(request.lines) };
});یادداشتها
- کارگر تنبلانه ساخته میشود، در نخستین
send: کار سنگین نباید همزمان با بارگذاری صفحه آغاز شود. - پیامهای پیشرفت درخواست را تعیین تکلیف نمیکنند، پس یک درخواست میتواند بهروزرسانیهای بسیاری بفرستد و باز هم در پایان یک بار برآورده شود.
- فروپاشی کارگر همهٔ درخواستهای در جریان را رد میکند. خطای گرفتهنشده درون کارگر
operationIdندارد، پس نمیتوان آن را به یک درخواست نسبت داد. dispose()تمام میکند و رد میکند؛sendبعدی کارگر را از نو میسازد.- پایان مهلت تنها همان درخواست را رد میکند و کارگر زنده میماند.
- برای بافرهای بزرگ از
transferاستفاده کنید تا بهجای رونوشت ساختاری، مالکیت جابهجا شود. serveWorkerخطاهای پرتابشدهٔ همگام را هم میگیرد. پرتاب همگام درونonmessageبه رسیدگیکنندهٔ خطای کارگر میگریزد و در آن مسیر هیچoperationIdهمراه نیست؛ آنگاه کارخواه ناچار است بهجای همان یکی که واقعاً شکست، همهٔ درخواستهای در جریان را ناکام کند.- اینکه هر دو نیمه با هم عرضه میشوند عمدی است. دستساز نوشتنِ سمت کارگر همان جایی است که بازتاب شناسه و پوششِ خطا میان پروژهها از هم دور میافتند.