Web Worker ב-TypeScript
מאמר זה מסביר על Web Workers ב-TypeScript.
ניתן ללמוד על הקונספט של Web Workers
וטיפים שונים לשימוש עם דוגמאות.
YouTube Video
Worker ב-TypeScript
ב-TypeScript, Worker
הוא מנגנון לעיבוד ברקע, נפרד מהשורה הראשית, תוך שימוש ב-API של JavaScript Web Workers. דבר זה מאפשר ביצוע חישובים כבדים ומשימות אסינכרוניות מבלי להשפיע על תפעול ממשק המשתמש.
Worker
פועל במקביל להשורה הראשית (UI thread) ויכול להחליף נתונים בין השורות באמצעות הודעות. גם ב-TypeScript, ניתן להשתמש ב-Worker
תוך כתיבת קוד עם בטיחות טיפוסים.
שימוש בסיסי ב-Worker
-
יצירת Worker
צרו מופע
Worker
והריצו את הסקריפט המוגדר. בד״כ הסקריפט מוגדר בקובץ נפרד. -
החלפת הודעות
שלחו וקבלו הודעות בין השורה הראשית לשורת ה-
Worker
באמצעותpostMessage
ו-onmessage
.
דוגמא: מימוש בסיסי של Worker
- worker.ts: סקריפט עבור Worker
1// worker.ts
2self.onmessage = (event) => {
3 const data = event.data;
4 const result = data.num1 + data.num2;
5 self.postMessage(result); // Return the result to the main thread
6};
- main.ts: סקריפט לשימוש ב-Worker בשורה הראשית
1// main.ts
2const worker = new Worker(
3 new URL('./worker.ts', import.meta.url),
4 { type: 'module' }
5);
6
7worker.onmessage = (event) => {
8 console.log("Result from worker:", event.data); // Receive message from the worker
9};
10
11worker.postMessage({ num1: 10, num2: 20 }); // Send message to the worker
- בדוגמא זו,
worker.ts
פועל בשורה נפרדת, מחשב את סכוםnum1
ו-num2
, ומחזיר את התוצאה לשורה הראשית. השורה הראשית מקבלת את התוצאה ומציגה אותה בקונסול. - כאשר אתה מציין
type: 'module'
, קובץ הסקריפט של העובד מפורש כמודול ES, מה שמאפשר להשתמש ב‑import ו‑export. זה מאפשר לך לטפל במבני מודולים מבלי להשתמש ב‑importScripts() המסורתי.
נקודות למחשבה בעת שימוש ב-Workers ב-TypeScript
הוספת הגדרות טיפוסים
ב-TypeScript, יש להגדיר טיפוסי נתונים כדי להבטיח אינטראקציה בטוחה של טיפוסים בעת שליחת וקבלת הודעות.
1// Define data types
2interface WorkerData {
3 num1: number;
4 num2: number;
5}
6
7interface WorkerResult {
8 result: number;
9}
10
11// worker.ts
12self.onmessage = (event: MessageEvent<WorkerData>) => {
13 const data = event.data;
14 const result = data.num1 + data.num2;
15 const message: WorkerResult = { result };
16 self.postMessage(message); // Send the result in a type-safe manner
17};
18
19// main.ts
20const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
21
22// Type the event from the worker
23worker.onmessage = (event: MessageEvent<WorkerResult>) => {
24 console.log("Result from worker:", event.data); // event.data is number
25};
26
27// Send typed data to the worker
28const message: WorkerData = { num1: 10, num2: 20 };
29worker.postMessage(message);
- על ידי ציון פרמטר הטיפוס של
MessageEvent
, ניתן להגדיר בבירור את סוג הנתונים שיש לקבל. דבר זה מאפשר חילופי נתונים עם בטיחות טיפוסים.
הגדרת Webpack או Vite
כאשר משתמשים ב-Worker
ב-TypeScript, ייתכן שיהיה צורך בשימוש בכלים כמו Webpack
או Vite
. באמצעות הכלים הללו, תוכלו לאגד (bundle) כראוי את קובץ ה-Worker
ולאפשר גישה אליו מה-Thread הראשי.
לדוגמה, כאשר משתמשים ב-Vite
, השתמשו ב-import.meta.url
כדי לייבא את ה-Worker
כהלכה.
1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
- זה מבטיח שקובץ ה-
Worker
המאוגד ייטען כראוי, ובכך יתאפשר עיבוד באמצעות ה-Worker
.
שיקולים להודעות ופעולה בו-זמנית
-
העתקת נתונים
בעת שליחת וקבלת הודעות בין ה-Thread הראשי ל-Thread של ה-
Worker
, הנתונים מועתקים. בעת עבודה עם נתונים מורכבים כגון אובייקטים, יש להתחשב ביעילות. החלפה תכופה של כמויות גדולות של נתונים עלולה לפגוע בביצועים. -
עצמים ניתנים להעברה (
Transferable
)חלק מהאובייקטים, כגון
ArrayBuffer
, נקראים אובייקטים 'הניתנים להעברה' (Transferable). אובייקטים שניתנים להעברה (Transferable) יכולים להיות מועברים ל-Worker במקום להיות מועתקים בזמן שליחת מסרים. שיטה זו מאפשרת לך להימנע מעומס נוסף שנובע מהעתקת נתונים.
1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2
3const buffer = new ArrayBuffer(1024);
4worker.postMessage(buffer, [buffer]); // Transfer ownership to the Worker
5
6console.log(buffer.byteLength); // 0 (ownership moved)
-
על ידי העברת
[buffer]
כארגומנט השני ל-worker.postMessage()
, ה-buffer מועבר ל-Worker במקום להיות מועתק. -
לאחר מכן, ה-buffer בתהליך הראשי מתאפס (עם אורך ביתים 0) ויכול לשמש רק את ה-Worker.
סיום שימוש ב-Worker
יש לסיים את פעולתו של ה-Worker
לאחר השימוש כדי לצמצם את צריכת הזיכרון. ניתן לסיים פעולתו של ה-Worker
באמצעות הפונקציה terminate
.
1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2// ...
3
4worker.terminate(); // Terminate the Worker
- קוד זה מסיים את ה-Worker באמצעות המתודה
terminate
.
טיפול בשגיאות ב-Worker
אם מתרחשת שגיאה בתוך ה-Worker
, ניתן לטפל בה באמצעות האירוע onerror
.
1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2
3worker.onerror = (error) => {
4 console.error("Error in Worker:", error.message);
5};
- קוד זה לוכד ומטפל בשגיאות שמתרחשות בתוך ה-Worker באמצעות אירוע
onerror
.
סיכום
על ידי שימוש ב-Worker
ב-TypeScript, ניתן לבצע משימות כבדות ברקע תוך שמירה על חלקות ה-Thread הראשי. באמצעות שימוש בהגדרות סוגים (type definitions), ניתן לבצע החלפת הודעות באופן בטוח מבחינת סוגים (type-safe). על ידי תשומת לב לניהול חילופי נתונים ו-Threads, ניתן להשיג שיפורי ביצועים ויעילות בפעולה בו-זמנית.
תוכלו לעקוב אחר המאמר שלמעלה באמצעות Visual Studio Code בערוץ היוטיוב שלנו. נא לבדוק גם את ערוץ היוטיוב.