عامل الويب في TypeScript

عامل الويب في TypeScript

تشرح هذه المقالة عمال الويب في TypeScript۔

يمكنك التعرف على مفهوم Web Workers ونصائح الاستخدام المختلفة مع أمثلة.۔

YouTube Video

العامل في TypeScript

في TypeScript، يعد العامل آلية لتنفيذ العمليات في الخلفية، بمعزل عن الخيط الأساسي، مستفيدًا من واجهة برمجة التطبيقات لعامل الويب في JavaScript۔ يتيح ذلك إجراء العمليات الحسابية الثقيلة والمهام غير المتزامنة دون التأثير على عمل واجهة المستخدم۔

يعمل العامل بالتوازي مع الخيط الرئيسي (خيط واجهة المستخدم) ويمكنه تبادل البيانات بين الخيوط عبر الرسائل۔ حتى في TypeScript، يمكنك استخدام العامل أثناء كتابة كود بآمان للأنواع۔

الاستخدام الأساسي للعامل

  1. إنشاء عامل

    أنشئ كائن عامل وقم بتنفيذ النص المحدد۔ عادةً ما يكون النص مكتوبًا في ملف منفصل۔

  2. تبادل الرسائل

    إرسال واستقبال الرسائل بين الخيط الرئيسي وخيط العامل باستخدام postMessage وonmessage۔

مثال: تنفيذ عامل أساسي

  1. worker.ts: نص للعامل
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};
  1. main.ts: نص لاستخدام العامل في الخيط الرئيسي
 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()۔

نقاط يجب مراعاتها عند استخدام العمال في 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۔ باستخدام هذه الأدوات، يمكنك تجميع نص Worker بشكل صحيح وجعله متاحًا من الخيط الرئيسي۔

على سبيل المثال، عند استخدام Vite، استخدم import.meta.url لاستيراد Worker بشكل صحيح۔

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
  • هذا يضمن تحميل نص Worker المجمع بشكل صحيح، مما يتيح المعالجة باستخدام Worker۔

الاعتبارات المتعلقة بالمراسلة والتعددية

  1. نسخ البيانات

    عند إرسال واستقبال الرسائل بين الخيط الرئيسي وخيط Worker، يتم نسخ البيانات۔ عند التعامل مع بيانات معقدة مثل الكائنات، يجب مراعاة الكفاءة۔ تبادل كميات كبيرة من البيانات بشكل متكرر يمكن أن يؤدي إلى ضعف الأداء۔

  2. الكائنات القابلة للنقل Transferable

    تسمى بعض الكائنات، مثل ArrayBuffer، كائنات قابلة للنقل (Transferable)۔ يمكن نقل الكائنات القابلة للنقل (Transferable) إلى العامل بدلاً من نسخها أثناء إرسال الرسائل۔ هذا يتيح لك تجنب الحمل الزائد لنسخ البيانات۔

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 إلى العامل بدلاً من نسخه۔

  • بعد ذلك، يصبح buffer في الخيط الرئيسي فارغًا (بقيمة byteLength تساوي 0) ولا يمكن استخدامه إلا من قبل العامل۔

إنهاء Worker

يجب إنهاء Worker بعد الاستخدام لتقليل استهلاك الذاكرة۔ يمكنك إنهاء Worker باستخدام طريقة terminate۔

1const worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });
2// ...
3
4worker.terminate(); // Terminate the 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};
  • يعترض هذا الكود الأخطاء التي تحدث داخل العامل ويتعامل معها باستخدام حدث onerror۔

الملخص

باستخدام Worker في TypeScript، يمكنك تنفيذ المهام الثقيلة في الخلفية مع الحفاظ على سلاسة الخيط الرئيسي۔ من خلال استخدام تعريفات النوع، يمكن تبادل الرسائل بطريقة آمنة من حيث النوع۔ من خلال الانتباه إلى تبادل البيانات وإدارة الخيوط، يمكنك تحقيق تحسينات في الأداء وتعددية الكفاءة۔

يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔

YouTube Video