الفرق بين المراجعتين لصفحة: «Node.js/worker threads»

من موسوعة حسوب
لا ملخص تعديل
ط استبدال النص - '\[\[تصنيف:(.*)\]\]' ب'{{SUBPAGENAME}}'
 
(3 مراجعات متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة)
سطر 1: سطر 1:
<noinclude>{{DISPLAYTITLE: وحدة الخيوط العاملة (Worker Threads) في Node.js}}</noinclude>
مؤشر الاستقرار: 1 - تجريبي
مؤشر الاستقرار: 1 - تجريبي


توفر وحدة worker طريقة لإنشاء بيئات متعددة تعمل علي خيوط مستقلة، ولإنشاء قنوات رسائل بينها. ويمكن الوصول إليها باستخدام الراية ‎--experimental-worker flag بالإضافة إلى:
توفر وحدة <code>worker</code> طريقة لإنشاء بيئات متعددة تعمل علي خيوط مستقلة، ولإنشاء قنوات رسائل بينها. ويمكن الوصول إليها باستخدام الراية ‎<code>--experimental-worker</code> flag بالإضافة إلى:<syntaxhighlight lang="javascript">
const worker = require('worker_threads');
</syntaxhighlight>وتفيد الخيوط العاملة (Workers) في أداء عمليات JavaScript كثيفة الاستخدام لوحدة المعالجة المركزية؛ ويجب ألَّا تستخدم في عمليات الإدخال والإخراج I/O، إذ تتعامل آلياتُ Node.js المدمجة لتنفيذ العمليات بشكل غير متزامن معها بشكل أكثر كفاءة من خيوط Worker.


وتفيد الخيوط العاملة (Workers) في أداء عمليات JavaScript كثيفة الاستخدام لوحدة المعالجة المركزية؛ ويجب ألَّا تستخدم في عمليات الإدخال والإخراج I/O، إذ تتعامل آلياتُ Node.js المدمجة لتنفيذ العمليات بشكل غير متزامن معها بشكل أكثر كفاءة من خيوط Worker.
علي عكس العمليات التابعة أو عند استخدام وحدة <code>cluster</code>، يمكن أيضًا أن تشارك الخيوطُ العاملةُ الذاكرةَ بكفاءة عن طريق نقل مثيلات <code>ArrayBuffer</code> أو مثيلات <code>sharingSharedArrayBuffer</code> فيما بينهما.<syntaxhighlight lang="javascript">
const {
  Worker, isMainThread, parentPort, workerData
} = require('worker_threads');


علي عكس العمليات التابعة أو عند استخدام وحدة cluster، يمكن أيضًا أن تشارك الخيوطُ العاملةُ الذاكرةَ بكفاءة عن طريق نقل مثيلات ArrayBuffer أو مثيلات sharingSharedArrayBuffer فيما بينهما.
if (isMainThread) {
 
  module.exports = async function parseJSAsync(script) {
لاحظ أن هذا المثال يولد خيط Worker لكل استدعاء تحليل parse. ومن الناحية العملية، يوصي بشدة باستخدام مجموعة من الخيوط العاملة (Workers) لهذه الأنواع من المهام، لان العبء المُحمَّل لإنشاء Workers قد يتجاوز على الأرجح الفائدة من تسليم العمل إليها.
    return new Promise((resolve, reject) => {
 
      const worker = new Worker(__filename, {
worker.isMainThread
        workerData: script
      });
      worker.on('message', resolve);
      worker.on('error', reject);
      worker.on('exit', (code) => {
        if (code !== 0)
          reject(new Error(`Worker stopped with exit code ${code}`));
      });
    });
  };
} else {
  const { parse } = require('some-js-parsing-library');
  const script = workerData;
  parentPort.postMessage(parse(script));
}
</syntaxhighlight>لاحظ أن هذا المثال يولد خيط Worker لكل استدعاء تحليل <code>parse</code>. ومن الناحية العملية، يوصي بشدة باستخدام مجموعة من الخيوط العاملة (Workers) لهذه الأنواع من المهام، لان العبء المُحمَّل لإنشاء Workers قد يتجاوز على الأرجح الفائدة من تسليم العمل إليها.


== <code>worker.isMainThread</code> ==
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* من النوع <code>[[JavaScript/Boolean|<boolean>]]</code>.
ويكون <code>true</code> إذا لم تكن هذه الشيفرة تعمل داخل خيط <code>Worker</code>.


من النوع <boolean>.
== <code>worker.parentPort</code> ==
 
ويكون true إذا لم تكن هذه الشيفرة تعمل داخل خيط Worker.
 
worker.parentPort
 
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* من النوع ‎<code>[[JavaScript/null|<null>]]</code> | <code><MessagePort></code>‎.
إذا نتج هذا الخيط كـ <code>Worker</code>، سيصبح هذا <code>MessagePort</code> يسمح بالاتصال مع الخيط الأصل. وستكون الرسائل المرسلة باستخدام <code>parentPort.postMessage()‎</code> متوفرة في الخيط الأصل باستخدام <code>worker.on('message')‎</code>، وستكون الرسائل المرسلة من الخيط الأصل باستخدام <code>worker.postMessage()</code>‎ متوفرة في هذا الخيط باستخدام <code>parentPort.on('message')‎</code>.


من النوع ‎<null> | <MessagePort>‎.
== <code>worker.threadId</code> ==
 
إذا نتج هذا الخيط كـ Worker، سيصبح هذا MessagePort يسمح بالاتصال مع الخيط الأصل. وستكون الرسائل المرسلة باستخدام parentPort.postMessage()‎ متوفرة في الخيط الأصل باستخدام worker.on('message')، وستكون الرسائل المرسلة من الخيط الأصل باستخدام worker.postMessage()‎ متوفرة في هذا الخيط باستخدام parentPort.on('message').
 
worker.threadId
 
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


من النوع <integer>.
من النوع <code>[[JavaScript/Number|<integer>]]</code>.


عدد صحيح مُعرِّف للخيط الحالي. إذا توفَّر كائن العامل المطابق، فانه يتوفر كـ worker.threadId.
عدد صحيح مُعرِّف للخيط الحالي. إذا توفَّر كائن العامل المطابق، فانه يتوفر كـ <code>worker.threadId</code>.
 
worker.workerData


== <code>worker.workerData</code> ==
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


قيمة JavaScript عشوائية تحتوي علي نسخة من البيانات التي مُرِرت إلى مُنشئ خيط Worker هذا.
قيمة JavaScript عشوائية تحتوي علي نسخة من البيانات التي مُرِرت إلى مُنشئ خيط <code>Worker</code> هذا.
 
الصنف: MessageChannel


== الصنف <code>MessageChannel</code> ==
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


تُمثل مثيلات الصنف worker.MessageChannel قناة اتصالات غير متزامنة، ثنائية الاتجاه. ليس لدي MessageChannel توابع خاصة بها. ويُعطي التابعُ MessageChannel()‎ الجديد كائنًا له الخصائص port1 و port2، والتي تشير إلى مثيلات MessagePort.
تُمثل مثيلات الصنف <code>worker.MessageChannel</code> قناة اتصالات غير متزامنة، ثنائية الاتجاه. ليس لدي <code>MessageChannel</code> توابع خاصة بها. ويُعطي التابعُ <code>MessageChannel()‎</code> الجديد كائنًا له الخصائص <code>port1</code> و <code>port2</code>، والتي تشير إلى مثيلات <code>MessagePort</code>.<syntaxhighlight lang="javascript">
const { MessageChannel } = require('worker_threads');


الصنف: MessagePort
const { port1, port2 } = new MessageChannel();
port1.on('message', (message) => console.log('received', message));
port2.postMessage({ foo: 'bar' });
// طباعة: received { foo: 'bar' } from the `port1.on('message')` listener
</syntaxhighlight>


== الصنف: <code>MessagePort</code> ==
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


يمتد: <EventEmitter>
يمتد: <code>[[Node.js/events|<EventEmitter>]]</code>.


تمثل مثيلات الصنف worker.MessagePort إحدى نهايتي قناة اتصالات غير متزامنة، ثنائية الاتجاه. ويمكن استخدامها لنقل البيانات المُهيكَلة، ومناطق الذاكرة و MessagePorts أخرى بين مختلف الـ Workers.
تمثل مثيلات الصنف <code>worker.MessagePort</code> إحدى نهايتي قناة اتصالات غير متزامنة، ثنائية الاتجاه. ويمكن استخدامها لنقل البيانات المُهيكَلة، ومناطق الذاكرة و <code>MessagePorts</code> أخرى بين مختلف الـ <code>Workers</code>.


مع استثناء MessagePorts كونه EventEmitters بدلًا من EventTargets، ويطابق هذا التطبيق MessagePorts الخاص بالمتصفح.
مع استثناء <code>MessagePorts</code> كونه <code>[[Node.js/events|EventEmitters]]</code> بدلًا من <code>EventTargets</code>، ويطابق هذا التطبيق [https://developer.mozilla.org/en-US/docs/Web/API/MessagePort <code>MessagePorts</code> الخاص بالمتصفح].
 
الحدث: 'close'


=== الحدث <code>'close'</code> ===
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


ينطلق الحدث 'close' بمجرد قطع الاتصال بأي من طرفي القناة.
ينطلق الحدث <code>'close'</code> بمجرد قطع الاتصال بأي من طرفي القناة.
 
الحدث: 'message'


=== الحدث <code>'message'</code> ===
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* <code>value</code> من أي نوع من الأنواع <any>. وهو القيمة المرسلة.
ينطلق الحدث <code>'message'</code> لأي رسالة واردة، تحتوي علي مُدخَل التابع <code>port.postMessage()‎</code> المُستنسَخ.


value من أي نوع من الأنواع <any>. وهو القيمة المرسلة.
سيتلقى المستمعون علي هذا الحدث نسخة من معامل القيمة كما مُرِر إلى التابع <code>postMessage()</code>‎ ولا توجد وسائط إضافية.
 
ينطلق الحدث 'message' لأي رسالة واردة، تحتوي علي مُدخَل التابع port.postMessage()‎ المُستنسَخ.
 
سيتلقى المستمعون علي هذا الحدث نسخة من معامل القيمة كما مُرِر إلى التابع postMessage()‎ ولا توجد وسائط إضافية.
 
port.close()‎


=== <code>port.close()‎</code> ===
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


يعطل إرسال المزيد من الرسائل علي أيٍ من طرفي الاتصال. يمكن استدعاء هذا التابع بمجرد معرفة انه لن يحدث المزيد من الاتصالات عبر MessagePort هذا.
يعطل إرسال المزيد من الرسائل علي أيٍ من طرفي الاتصال. يمكن استدعاء هذا التابع بمجرد معرفة انه لن يحدث المزيد من الاتصالات عبر <code>MessagePort</code> هذا.
 
port.postMessage(value[, transferList])


=== <code>port.postMessage(value[, transferList])‎</code> ===
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* <code>value</code> من أي نوع من الأنواع <code><any></code>.
* <code>transferList</code> من النوع ‎<code>[[JavaScript/Object|<Object[]>]]</code>‎.
إرسال قيمة JavaScript إلى الجانب المتلقي من هذه القناة. ستتنقل القيمة بطريقة متوافقة مع [https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm خوارزمية استنساخ HTML المُهيكلة]. ولا سيما أنها قد تحتوي على مراجع دورية وكائنات مثل مصفوفات مكتوبة والتي لا تستطيع واجهات تطبيقات <code>JSON</code> تحويلها إلى سلسلة نصية.


value من أي نوع من الأنواع <any>.
<code>transferList</code> قد تكون قائمة من كائنات <code>ArrayBuffer</code> و <code>MessagePort</code>. ولن تكون قابلة للاستخدام علي الجانب المرسل من القناة بعد النقل (حتى لو لم تكن موجودة في <code>value</code>). وخلافًا [[Node.js/child process|للعمليات الأبناء]]، لا يُدعم نقل المعالجات مثل مقابس الشبكة حاليًا.
 
transferList من النوع ‎<Object[]>
 
إرسال قيمة JavaScript إلى الجانب المتلقي من هذه القناة. ستتنقل القيمة بطريقة متوافقة مع خوارزمية استنساخ HTML المُهيكلة. ولا سيما أنها قد تحتوي على مراجع دورية وكائنات مثل مصفوفات مكتوبة والتي لا تستطيع واجهات تطبيقات JSON تحويلها إلى سلسلة نصية.
 
transferList قد تكون قائمة من كائنات ArrayBuffer و MessagePort. ولن تكون قابلة للاستخدام علي الجانب المرسل من القناة بعد النقل (حتى لو لم تكن موجودة في value). وخلافًا للعمليات التابعة، لا يُدعم نقل المعالجات مثل مقابس الشبكة حاليًا.


إذا احتوي value على مثيلات SharedArrayBuffer، ستكون هذه متاحة من أيٍ من الطرفين. ولا يمكن إدراجها في transferList.
إذا احتوي <code>value</code> على مثيلات <code>[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer SharedArrayBuffer]</code>، ستكون هذه متاحة من أيٍ من الطرفين. ولا يمكن إدراجها في <code>transferList</code>.


قد لا يزال value يحتوي على مثيلات ArrayBuffer غير الموجودة في transferList؛ في هذه الحالة تنسخ الذاكرة الأساسية بدلًا من نقلها.
قد لا يزال <code>value</code> يحتوي على مثيلات <code>ArrayBuffer</code> غير الموجودة في <code>transferList</code>؛ في هذه الحالة تنسخ الذاكرة الأساسية بدلًا من نقلها.


لان استنساخ الكائن يستخدم خوارزمية الاستنساخ المُهيكَلة، لا يحتفظ بالخصائص غير القابلة للعد، ومُوصِّلات الخاصية (property accessors)، والنماذج الأولية للكائن. علي وجه الخصوص، ستُقرأ كائنات Buffer على أنها Uint8Arrays عادية عند الطرف المُتلقِّي.
لان استنساخ الكائن يستخدم خوارزمية الاستنساخ المُهيكَلة، لا يحتفظ بالخصائص غير القابلة للعد، ومُوصِّلات الخاصية (property accessors)، والنماذج الأولية للكائن. علي وجه الخصوص، ستُقرأ كائنات <code>[[Node.js/buffer|Buffer]]</code> على أنها <code>[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array Uint8Arrays]</code> عادية عند الطرف المُتلقِّي.


سيُستنسخ الكائن message فورًا، ويمكن تعديله بعد النشر دون وجود تأثيرات جانبية.
سيُستنسخ الكائن message فورًا، ويمكن تعديله بعد النشر دون وجود تأثيرات جانبية.


للحصول علي مزيد من المعلومات حول آليات التسلسل وإلغاء التسلسل من وراء هذه الـ API، راجع واجهات تطبيق التسلسل في الوحدة v8.
للحصول علي مزيد من المعلومات حول آليات التسلسل وإلغاء التسلسل من وراء هذه الـ API، راجع [[Node.js/v8|واجهات تطبيق التسلسل في الوحدة v8]].
 
port.ref()‎


=== <code>port.ref()‎</code> ===
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


مقابل unref()‎. استدعاء ref()‎ على منفذ سبق إجراء unref عليه لن يسمح للبرنامج بالانتهاء إذا كان هو المعالج الوحيد المتبقي (السلوك الافتراضي). استدعاء ref()‎ مرة أخرى على منفذ سبق إجراء ref عليه لن يكون له أي تأثير.
مقابل <code>unref()‎</code>. استدعاء <code>ref()‎</code> على منفذ سبق إجراء <code>unref</code> عليه لن يسمح للبرنامج بالانتهاء إذا كان هو المعالج الوحيد المتبقي (السلوك الافتراضي). استدعاء <code>ref()‎</code> مرة أخرى على منفذ سبق إجراء <code>ref</code> عليه لن يكون له أي تأثير.


إذا كان المستمعون متصلين أو أزيلوا باستخدام ‎.on('message')، سيُطبق على المنفذ التوابع ref()‎ و unref()‎‎ تلقائيًا اعتمادًا علي وجود مستمعين للحدث.
إذا كان المستمعون متصلين أو أزيلوا باستخدام <code>‎.on('message')‎</code>، سيُطبق على المنفذ التوابع <code>ref()‎</code> و <code>unref()‎‎</code> تلقائيًا اعتمادًا علي وجود مستمعين للحدث.
 
port.start()‎


=== <code>port.start()‎</code> ===
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


بدء تلقي الرسائل علي MessagePort هذا. عند استخدام هذا المنفذ كمُطلِق للحدث، سيُستدعى هذا التابع تلقائيًا بمجرد إرفاق مستمعي الحدث 'message'.
بدء تلقي الرسائل علي <code>MessagePort</code> هذا. عند استخدام هذا المنفذ كمُطلِق للحدث، سيُستدعى هذا التابع تلقائيًا بمجرد إرفاق مستمعي الحدث <code>'message'</code>.
 
port.unref()‎


=== <code>port.unref()‎</code> ===
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


يسمح استدعاء unref()‎ على منفذ للخيط بالإنهاء إذا كان هو المعالج النشط الوحيد في نظام الأحداث. استدعاء unref()‎ مرة أخرى على منفذ سبق إجراء unref عليه لن يكون له أي تأثير.
يسمح استدعاء <code>unref()</code>‎ على منفذ للخيط بالإنهاء إذا كان هو المعالج النشط الوحيد في نظام الأحداث. استدعاء <code>unref()‎</code> مرة أخرى على منفذ سبق إجراء <code>unref</code> عليه لن يكون له أي تأثير.


إذا كان المستمعون متصلين أو أُزيلوا باستخدام ‎.on('message')، سيُطبق على المنفذ التوابع ref()‎ و unref()‎‎ تلقائيًا اعتمادًا علي وجود مستمعين للحدث.
إذا كان المستمعون متصلين أو أُزيلوا باستخدام <code>‎.on('message')‎</code>، سيُطبق على المنفذ التوابع <code>ref()</code>‎ و <code>unref()</code>‎‎ تلقائيًا اعتمادًا علي وجود مستمعين للحدث.
 
الصنف: Worker


== الصنف <code>Worker</code> ==
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


يمثل الصنف Worker خيط تنفيذ JavaScript مستقل. تتوفر معظم واجهات تطبيقات Node.js داخله.
يمثل الصنف <code>Worker</code> خيط تنفيذ JavaScript مستقل. تتوفر معظم واجهات تطبيقات Node.js داخله.


ومن أبرز هذه الاختلافات داخل بيئة Worker:
ومن أبرز هذه الاختلافات داخل بيئة Worker:
 
* قد يُعاد توجيه <code>[[Node.js/process|process.stdin]]</code> و <code>[[Node.js/process|process.stdout]]</code> و <code>[[Node.js/process|process.stderr]]</code> بواسطة الخيط الأصل.
قد يُعاد توجيه process.stdin و process.stdout و process.stderr بواسطة الخيط الأصل.
* تُضبط الخاصية <code>require('worker_threads').isMainThread</code> بالقيمة <code>false</code>.
 
* يصبح منفذ الرسالة <code>require('worker_threads').parentPort</code> متاحًا،
تُضبط الخاصية require('worker_threads').isMainThread بالقيمة false.
* ولا يوقف التابعُ <code>[[Node.js/process|process.exit()]]</code>‎ البرنامجَ بأكمله، فقط الخيطَ منفردًا، ولا يُتاح <code>[[Node.js/process|process.abort()]]</code>‎.
 
* ولا يُتاح <code>[[Node.js/process|process.chdir()]]</code>‎ ولا توابع العمليات التي تضبط مُعرِّفات المجموعة أو المستخدم.
يصبح منفذ الرسالة require('worker_threads').parentPort متاحًا،
* <code>[[Node.js/process|process.env]]</code> هو مرجع للقراءة فقط إلى متغيرات البيئة.
 
* لا يمكن تعديل <code>[[Node.js/process|process.title]]</code>.
ولا يوقف التابعُ process.exit()‎ البرنامجَ بأكمله، فقط الخيطَ منفردًا، ولا يُتاح process.abort()‎.
* لن تُسلَّم الإشارات من خلال <code>[[Node.js/process|process.on('...')]]</code>‎‎.
 
* قد يتوقف التنفيذ عند أي نقطة نتيجة لاستدعاء التابع <code>[[Node.js/process|worker.terminate()‎]]</code>.
ولا يُتاح process.chdir()‎ ولا توابع العمليات التي تضبط مُعرِّفات المجموعة أو المستخدم.
* لا يمكن الوصول إلى قنوات IPC من العمليات الأصلية.
 
process.env هو مرجع للقراءة فقط إلى متغيرات البيئة.
 
لا يمكن تعديل process.title.
 
لن تُسلَّم الإشارات من خلال process.on('...')‎‎.
 
قد يتوقف التنفيذ عند أي نقطة نتيجة لاستدعاء التابع worker.terminate()‎.
 
لا يمكن الوصول إلى قنوات IPC من العمليات الأصلية.
 
وتوجد حاليًا الاختلافات التالية أيضا، إلى أن يتم معالجتها:
وتوجد حاليًا الاختلافات التالية أيضا، إلى أن يتم معالجتها:
* وحده <code>[[Node.js/inspector|inspector]]</code> غير مُتاحة حتى الآن.
* الإضافات الأصلية غير مدعومة حتى الآن.
يمكن إنشاء مثيلات <code>Worker</code> داخل <code>Worker</code> آخرين.


وحده inspector غير مُتاحة حتى الآن.
مثلما هو الحال مع [https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API Web Workers] و<nowiki/>[[Node.js/cluster|وحدة <code>cluster</code>]]، يمكن تحقيق الاتصالات في اتجاهين من خلال تمرير الرسائل بين الخيوط. يحتوي Worker داخليَا على زوج مُضمَّن من MessagePorts المقترن بالفعل مع بعضه البعض عند إنشاء الكائن <code>Worker</code>. في حين لا يكون الكائن <code>MessagePort</code> علي جانب الأصل مُستهدَفًا بشكل مباشر، تكون وظائفه مُستهدَفة من خلال التابع <code>worker.postMessage()‎</code> والحدث <code>worker.on('message')‎</code> علي الكائن <code>Worker</code> لخيط الأصل.


الإضافات الأصلية غير مدعومة حتى الآن.
لإنشاء قنوات المراسلة المخصصة (والتي يُفضَّل استخدامها عن استخدام القناة العامة الافتراضية لأنها تُسهِّل فصل الاهتمامات)، يمكن للمستخدمين إنشاء كائن <code>MessageChannel</code> علي أي خيط وتمرير أحد <code>MessagePorts</code> علي هذه <code>MessageChannel</code> إلى الخيط الآخر من خلال قناة موجودة من قبل، مثل القناة العامة.


يمكن إنشاء مثيلات Worker داخل Workers آخرين.
راجع <code>port.postMessage()</code>‎ للحصول علي مزيد من المعلومات حول كيفية تمرير الرسائل، وماهية نوع قيم JavaScript التي يمكن نقلها بنجاح عبر حاجز الخيط.<syntaxhighlight lang="javascript">
const assert = require('assert');
const {
  Worker, MessageChannel, MessagePort, isMainThread, parentPort
} = require('worker_threads');
if (isMainThread) {
  const worker = new Worker(__filename);
  const subChannel = new MessageChannel();
  worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]);
  subChannel.port2.on('message', (value) => {
    console.log('received:', value);
  });
} else {
  parentPort.once('message', (value) => {
    assert(value.hereIsYourPort instanceof MessagePort);
    value.hereIsYourPort.postMessage('يرسل العامل هذا');
    value.hereIsYourPort.close();
  });
}
</syntaxhighlight>


مثلما هو الحال مع Web Workers ووحدة cluster، يمكن تحقيق الاتصالات في اتجاهين من خلال تمرير الرسائل بين الخيوط. يحتوي Worker داخليَا على زوج مُضمَّن من MessagePorts المقترن بالفعل مع بعضه البعض عند إنشاء الكائن Worker. في حين لا يكون الكائن MessagePort علي جانب الأصل مُستهدَفًا بشكل مباشر، تكون وظائفه مُستهدَفة من خلال التابع worker.postMessage()والحدث worker.on('message') علي الكائن Worker لخيط الأصل.
====== <code>new Worker(filename[, options])‎</code> ======
<code>filename</code> من النوع <code>[[JavaScript/String|<string>]]</code>، وهو المسار إلى سكريبت Worker الرئيسي. يجب أن يكون إمَّا مسارًا مطلقًا أو مسارًا نسبيًا (أي بالنسبة إلى دليل العمل الحالي) بدءًا من <code>‎./</code>‎ أو <code>‎../</code>‎. إذا كانت options.eval قيمتها true، تكون هذه سلسلة نصية تحتوي علي شيفرة JavaScript بدلًا من المسار.


لإنشاء قنوات المراسلة المخصصة (والتي يُفضَّل استخدامها عن استخدام القناة العامة الافتراضية لأنها تُسهِّل فصل الاهتمامات)، يمكن للمستخدمين إنشاء كائن MessageChannel علي أي خيط وتمرير أحد MessagePorts علي هذه MessageChannel إلى الخيط الآخر من خلال قناة موجودة من قبل، مثل القناة العامة.
<code>options</code> من النوع <code>[[JavaScript/Object|<Object>]]</code>.
 
* <code>eval</code> من النوع <code>[[JavaScript/Boolean|<boolean>]]</code>، إذا كان <code>true</code>، تفسر الوسيط الأول للمُنشئ كسكريبت يُنفَّذ فور اتصال العامل.
راجع port.postMessage()‎ للحصول علي مزيد من المعلومات حول كيفية تمرير الرسائل، وماهية نوع قيم JavaScript التي يمكن نقلها بنجاح عبر حاجز الخيط.
* <code>workerdata</code> من أي نوع من الأنواع <code><any></code>، أي قيمة JavaScript ستُستنسَخ وتصبح متاحة في الصورة <code>require('worker_threads').workerData</code>. سيحدث الاستنساخ كما هو موضح في [https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm خوارزمية استنساخ HTML المُهيكَلة]، وسينطلق خطأ إذا كان لا يمكن استنساخ الكائن (علي سبيل المثال لأنه يحتوي علي دوال).
 
* <code>stdin</code> من النوع <code>[[JavaScript/Boolean|<boolean>]]</code>، إذا ضُبط بالقيمة <code>true</code>، سيوفر <code>worker.stdin</code> دفق قابل للكتابة والذي تظهر محتوياته كـ <code>process.stdin</code> داخل Worker. بشكل افتراضي، لا تتوفر أي بيانات.
new Worker(filename[, options])
* <code>stdout</code> من النوع <code>[[JavaScript/Boolean|<boolean>]]</code>، إذا ضُبط بالقيمة <code>true</code>، لن يُوجَّه <code>worker.stdout</code> تلقائيًا من خلاله إلى <code>process.stdout</code> في الأصل.
 
* <code>stderr</code> من النوع <code>[[JavaScript/Boolean|<boolean>]]</code>، إذا ضُبط بالقيمة <code>true</code>، لن يُوجَّه <code>worker.stder</code>r تلقائيًا من خلاله إلى <code>process.stderr</code> في الأصل.
filename من النوع <string>، وهو المسار إلى سكريبت Worker الرئيسي. يجب أن يكون إمَّا مسارًا مطلقًا أو مسارًا نسبيًا (أي بالنسبة إلى دليل العمل الحالي) بدءًا من ‎./‎ أو ‎../‎. إذا كانت options.eval قيمتها true، تكون هذه سلسلة نصية تحتوي علي شيفرة JavaScript بدلًا من المسار.
 
options من النوع <Object>.
 
eval من النوع <boolean>، إذا كان true، تفسر الوسيط الأول للمُنشئ كسكريبت يُنفَّذ فور اتصال العامل.
 
workerdata من أي نوع من الأنواع <any>، أي قيمة JavaScript ستُستنسَخ وتصبح متاحة في الصورة require('worker_threads').workerData. سيحدث الاستنساخ كما هو موضح في خوارزمية استنساخ HTML المُهيكَلة، وسينطلق خطأ إذا كان لا يمكن استنساخ الكائن (علي سبيل المثال لأنه يحتوي علي دوال).
 
stdin من النوع <boolean>، إذا ضُبط بالقيمة true، سيوفر worker.stdin دفق قابل للكتابة والذي تظهر محتوياته كـ process.stdin داخل Worker. بشكل افتراضي، لا تتوفر أي بيانات.
 
stdout من النوع <boolean>، إذا ضُبط بالقيمة true، لن يُوجَّه worker.stdout تلقائيًا من خلاله إلى process.stdout في الأصل.
 
stderr من النوع <boolean>، إذا ضُبط بالقيمة true، لن يُوجَّه worker.stderr تلقائيًا من خلاله إلى process.stderr في الأصل.
 
الحدث: 'error'


=== الحدث <code>'error'</code> ===
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* <code>err</code> من النوع <code>[[Node.js/error|<Error>]]</code>.
سينطلق الحدث <code>'error'</code> إذا أجرى الخيط العامل استثناءً غير مُلتقَط. في هذه الحالة، سيتم إنهاء العامل.


err من النوع <Error>.
=== الحدث <code>'exit'</code> ===
 
سينطلق الحدث 'error' إذا أجرى الخيط العامل استثناءً غير مُلتقَط. في هذه الحالة، سيتم إنهاء العامل.
 
الحدث: 'exit'
 
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* <code>exitcode</code> من النوع <code>[[JavaScript/Number|<integer>]]</code>.
ينطلق الحدث <code>'exit'</code> بمجرد توقف العامل. إذا أٌُنهي العامل باستدعاء <code>process.exit()‎</code>، سيكون المعامل <code>exitCode</code> هو رمز الإنهاء الذي مُرِر. إذا أُنهي العامل، سيكون المعامل <code>exitCode</code> قيمته <code>1</code>.


exitcode من النوع <integer>.
=== الحدث <code>'message'</code> ===
 
ينطلق الحدث 'exit' بمجرد توقف العامل. إذا أٌُنهي العامل باستدعاء process.exit()‎، سيكون المعامل exitCode هو رمز الإنهاء الذي مُرِر. إذا أُنهي العامل، سيكون المعامل exitCode قيمته 1.
 
الحدث: 'message'
 
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* <code>value</code> من أي نوع من الأنواع <code><any></code>. وهو القيمة المُرسَلة.
ينطلق الحدث <code>'message'</code> عند استدعاء الخيط العامل للتابع <code>require('worker_threads').postMessage()‎</code>. راجع الحدث <code>port.on('message')‎</code> للحصول علي مزيد من التفاصيل.


value من أي نوع من الأنواع <any>. وهو القيمة المُرسَلة.
=== الحدث <code>'online'</code> ===
 
ينطلق الحدث 'message' عند استدعاء الخيط العامل للتابع require('worker_threads').postMessage()‎. راجع الحدث port.on('message') للحصول علي مزيد من التفاصيل.
 
الحدث: 'online'
 
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


ينطلق الحدث 'online' عند بدء الخيط العامل في تنفيذ شيفرة JavaScript البرمجية.
ينطلق الحدث <code>'online'</code> عند بدء الخيط العامل في تنفيذ شيفرة JavaScript البرمجية.
 
worker.postMessage(value[, transferList])


=== <code>worker.postMessage(value[, transferList])‎</code> ===
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* <code>value</code> من أي نوع من الأنواع <code><any></code>.
* <code>transferList</code> من النوع ‎<code>[[JavaScript/Object|<Object[]>]]</code>‎.
إرسال رسالة للعامل يستلمها من خلال <code>require('worker_threads').parentPort.on('message')‎.</code> راجع <code>port.postMessage()</code>‎ للحصول علي مزيد من التفاصيل.


value من أي نوع من الأنواع <any>.
=== <code>worker.ref()‎</code> ===
 
transferList من النوع ‎<Object[]>‎.
 
إرسال رسالة للعامل يستلمها من خلال require('worker_threads').parentPort.on('message'). راجع port.postMessage()‎ للحصول علي مزيد من التفاصيل.
 
worker.ref()‎
 
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


على عكس unref()‎، استدعاء ref()‎ على عامل سبق إجراء unref عليه لن يسمح للبرنامج بالانتهاء إذا كان هو المُعالج الوحيد المتبقي (السلوك الافتراضي). استدعاء ref()‎ مرة أخرى على عامل سبق إجراء ref عليه لن يكون له أي تأثير.
على عكس <code>unref()‎</code>، استدعاء <code>ref()</code>‎ على عامل سبق إجراء <code>unref</code> عليه لن يسمح للبرنامج بالانتهاء إذا كان هو المُعالج الوحيد المتبقي (السلوك الافتراضي). استدعاء <code>ref()‎</code> مرة أخرى على عامل سبق إجراء <code>ref</code> عليه لن يكون له أي تأثير.
 
worker.stderr


=== <code>worker.stderr</code> ===
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* من النوع <code>[[Node.js/stream|<stream.Readable>]]</code>.
وهو دفق قابل للقراءة يحتوي علي البيانات المكتوبة على <code>[[Node.js/process|process.stderr]]</code> داخل خيط العامل. إذا لم تُمرر <code>stderr: true</code> لمُنشِئ <code>Worker</code>، ستُوجَّه البيانات إلى دفق <code>[[Node.js/process|process.stderr]]</code> لخيط الأصل.


من النوع <stream.Readable>.
=== <code>worker.stdin</code> ===
 
وهو دفق قابل للقراءة يحتوي علي البيانات المكتوبة على process.stderr داخل خيط العامل. إذا لم تُمرر stderr: true لمُنشِئ Worker، ستُوجَّه البيانات إلى دفق process.stderr لخيط الأصل.
 
worker.stdin
 
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* من النوع ‎<code>[[JavaScript/null|<null>]]</code> | <code>[[Node.js/stream|<stream.Writable>]]</code>‎.
إذا مُررت <code>stdin: true</code> لمُنشِئ <code>Worker</code>، يكون ذلك دفق قابل للكتابة. ستُتاح البيانات المكتوبة إلى دفق <code>[[Node.js/process|process.stdin]]</code> في الخيط العامل.


من النوع ‎<null> | <stream.Writable>‎
=== <code>worker.stdout</code> ===
 
إذا مُررت stdin: true لمُنشِئ Worker، يكون ذلك دفق قابل للكتابة. ستُتاح البيانات المكتوبة إلى دفق process.stdin في الخيط العامل.
 
worker.stdout
 
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* من النوع <code>[[Node.js/stream|<stream.Readable>]]</code>.
وهو دفق قابل للقراءة يحتوي علي البيانات المكتوبة على <code>[[Node.js/process|process.stdout]]</code> داخل خيط العامل. إذا مُررت <code>stdout: true</code> لمُنشِئ <code>Worker</code>، ستوجه البيانات إلى دفق <code>[[Node.js/process|process.stdout]]</code> لخيط الأصل.


<stream.Readable>
=== <code>worker.terminate([callback])‎</code> ===
 
وهو دفق قابل للقراءة يحتوي علي البيانات المكتوبة على process.stdout داخل خيط العامل. إذا مُررت stdout: true لمُنشِئ Worker، ستوجه البيانات إلى دفق process.stdout لخيط الأصل.
 
worker.terminate([callback])
 
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* <code>callback</code> من النوع <code>[[JavaScript/Function|<Function>]]</code>.
إيقاف تنفيذ كافة JavaScript في الخيط العامل في أقرب وقت ممكن. <code>callback</code> هو دالة اختيارية تُستدعى بمجرد معرفة اكتمال هذه العملية.


callback من النوع <Function>.
تحذير: حاليًا، ليست جميع الشيفرات البرمجية الداخلية في Node.js مستعدة لتوقع الإنهاء في نقاط عشوائية في الوقت المناسب وقد يتلف إذا واجه هذا الظرف. وبناءً على لذلك، يجب حاليًا فقط استدعاء ‎<code>.terminate()‎</code> إذا كان من المعروف أن الخيط العامل لا يمكنه الوصول إلى الوحدات الأساسية من Node.js غير المعروض في وحدة العامل.
 
إيقاف تنفيذ كافة JavaScript في الخيط العامل في أقرب وقت ممكن. callback هو دالة اختيارية تُستدعى بمجرد معرفة اكتمال هذه العملية.
 
تحذير: حاليًا، ليست جميع الشيفرات البرمجية الداخلية في Node.js مستعدة لتوقع الإنهاء في نقاط عشوائية في الوقت المناسب وقد يتلف إذا واجه هذا الظرف. وبناءً على لذلك، يجب حاليًا فقط استدعاء .terminate()‎ إذا كان من المعروف أن الخيط العامل لا يمكنه الوصول إلى الوحدات الأساسية من Node.js غير المعروض في وحدة العامل.
 
worker.threadId


=== <code>worker.threadId</code> ===
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.
* من النوع <code>[[JavaScript/Number|<integer>]]</code>.
عدد صحيح مُعرِّف للخيط المشار إليه. داخل الخيط العامل، ويكون متوفرًا في الصورة <code>require('worker_threads').threadId</code>.


من النوع <integer>.
=== <code>worker.unref()‎</code> ===
 
عدد صحيح مُعرِّف للخيط المشار إليه. داخل الخيط العامل، ويكون متوفرًا في الصورة require('worker_threads').threadId.
 
worker.unref()‎
 
أضيف مع الإصدار: v10.5.0.
أضيف مع الإصدار: v10.5.0.


يسمح استدعاء unref()‎ على عامل للخيط بالإنهاء إذا كان هو المعالج النشط الوحيد في نظام الأحداث. استدعاء unref()‎ مرة أخرى على عامل سبق إجراء unref عليه لن يكون له أي تأثير.
يسمح استدعاء <code>unref()‎</code> على عامل للخيط بالإنهاء إذا كان هو المعالج النشط الوحيد في نظام الأحداث. استدعاء <code>unref()</code>‎ مرة أخرى على عامل سبق إجراء <code>unref</code> عليه لن يكون له أي تأثير.
 
مصادر


صفحة الخيوط العاملة (Worker Threads) في توثيق Node.js الرسمي.
== مصادر ==
* <span> </span>[https://nodejs.org/dist/latest-v10.x/docs/api/worker_threads.html صفحة الخيوط العاملة (Worker Threads) في توثيق Node.js الرسمي].
[[تصنيف:Node.js|{{SUBPAGENAME}}]]

المراجعة الحالية بتاريخ 11:15، 23 أكتوبر 2018

مؤشر الاستقرار: 1 - تجريبي

توفر وحدة worker طريقة لإنشاء بيئات متعددة تعمل علي خيوط مستقلة، ولإنشاء قنوات رسائل بينها. ويمكن الوصول إليها باستخدام الراية ‎--experimental-worker flag بالإضافة إلى:

const worker = require('worker_threads');

وتفيد الخيوط العاملة (Workers) في أداء عمليات JavaScript كثيفة الاستخدام لوحدة المعالجة المركزية؛ ويجب ألَّا تستخدم في عمليات الإدخال والإخراج I/O، إذ تتعامل آلياتُ Node.js المدمجة لتنفيذ العمليات بشكل غير متزامن معها بشكل أكثر كفاءة من خيوط Worker. علي عكس العمليات التابعة أو عند استخدام وحدة cluster، يمكن أيضًا أن تشارك الخيوطُ العاملةُ الذاكرةَ بكفاءة عن طريق نقل مثيلات ArrayBuffer أو مثيلات sharingSharedArrayBuffer فيما بينهما.

const {
  Worker, isMainThread, parentPort, workerData
} = require('worker_threads');

if (isMainThread) {
  module.exports = async function parseJSAsync(script) {
    return new Promise((resolve, reject) => {
      const worker = new Worker(__filename, {
        workerData: script
      });
      worker.on('message', resolve);
      worker.on('error', reject);
      worker.on('exit', (code) => {
        if (code !== 0)
          reject(new Error(`Worker stopped with exit code ${code}`));
      });
    });
  };
} else {
  const { parse } = require('some-js-parsing-library');
  const script = workerData;
  parentPort.postMessage(parse(script));
}

لاحظ أن هذا المثال يولد خيط Worker لكل استدعاء تحليل parse. ومن الناحية العملية، يوصي بشدة باستخدام مجموعة من الخيوط العاملة (Workers) لهذه الأنواع من المهام، لان العبء المُحمَّل لإنشاء Workers قد يتجاوز على الأرجح الفائدة من تسليم العمل إليها.

worker.isMainThread

أضيف مع الإصدار: v10.5.0.

ويكون true إذا لم تكن هذه الشيفرة تعمل داخل خيط Worker.

worker.parentPort

أضيف مع الإصدار: v10.5.0.

  • من النوع ‎<null> | <MessagePort>‎.

إذا نتج هذا الخيط كـ Worker، سيصبح هذا MessagePort يسمح بالاتصال مع الخيط الأصل. وستكون الرسائل المرسلة باستخدام parentPort.postMessage()‎ متوفرة في الخيط الأصل باستخدام worker.on('message')‎، وستكون الرسائل المرسلة من الخيط الأصل باستخدام worker.postMessage()‎ متوفرة في هذا الخيط باستخدام parentPort.on('message')‎.

worker.threadId

أضيف مع الإصدار: v10.5.0.

من النوع <integer>.

عدد صحيح مُعرِّف للخيط الحالي. إذا توفَّر كائن العامل المطابق، فانه يتوفر كـ worker.threadId.

worker.workerData

أضيف مع الإصدار: v10.5.0.

قيمة JavaScript عشوائية تحتوي علي نسخة من البيانات التي مُرِرت إلى مُنشئ خيط Worker هذا.

الصنف MessageChannel

أضيف مع الإصدار: v10.5.0.

تُمثل مثيلات الصنف worker.MessageChannel قناة اتصالات غير متزامنة، ثنائية الاتجاه. ليس لدي MessageChannel توابع خاصة بها. ويُعطي التابعُ MessageChannel()‎ الجديد كائنًا له الخصائص port1 و port2، والتي تشير إلى مثيلات MessagePort.

const { MessageChannel } = require('worker_threads');

const { port1, port2 } = new MessageChannel();
port1.on('message', (message) => console.log('received', message));
port2.postMessage({ foo: 'bar' });
// طباعة: received { foo: 'bar' } from the `port1.on('message')` listener

الصنف: MessagePort

أضيف مع الإصدار: v10.5.0.

يمتد: <EventEmitter>.

تمثل مثيلات الصنف worker.MessagePort إحدى نهايتي قناة اتصالات غير متزامنة، ثنائية الاتجاه. ويمكن استخدامها لنقل البيانات المُهيكَلة، ومناطق الذاكرة و MessagePorts أخرى بين مختلف الـ Workers.

مع استثناء MessagePorts كونه EventEmitters بدلًا من EventTargets، ويطابق هذا التطبيق MessagePorts الخاص بالمتصفح.

الحدث 'close'

أضيف مع الإصدار: v10.5.0.

ينطلق الحدث 'close' بمجرد قطع الاتصال بأي من طرفي القناة.

الحدث 'message'

أضيف مع الإصدار: v10.5.0.

  • value من أي نوع من الأنواع <any>. وهو القيمة المرسلة.

ينطلق الحدث 'message' لأي رسالة واردة، تحتوي علي مُدخَل التابع port.postMessage()‎ المُستنسَخ.

سيتلقى المستمعون علي هذا الحدث نسخة من معامل القيمة كما مُرِر إلى التابع postMessage()‎ ولا توجد وسائط إضافية.

port.close()‎

أضيف مع الإصدار: v10.5.0.

يعطل إرسال المزيد من الرسائل علي أيٍ من طرفي الاتصال. يمكن استدعاء هذا التابع بمجرد معرفة انه لن يحدث المزيد من الاتصالات عبر MessagePort هذا.

port.postMessage(value[, transferList])‎

أضيف مع الإصدار: v10.5.0.

  • value من أي نوع من الأنواع <any>.
  • transferList من النوع ‎<Object[]>‎.

إرسال قيمة JavaScript إلى الجانب المتلقي من هذه القناة. ستتنقل القيمة بطريقة متوافقة مع خوارزمية استنساخ HTML المُهيكلة. ولا سيما أنها قد تحتوي على مراجع دورية وكائنات مثل مصفوفات مكتوبة والتي لا تستطيع واجهات تطبيقات JSON تحويلها إلى سلسلة نصية.

transferList قد تكون قائمة من كائنات ArrayBuffer و MessagePort. ولن تكون قابلة للاستخدام علي الجانب المرسل من القناة بعد النقل (حتى لو لم تكن موجودة في value). وخلافًا للعمليات الأبناء، لا يُدعم نقل المعالجات مثل مقابس الشبكة حاليًا.

إذا احتوي value على مثيلات SharedArrayBuffer، ستكون هذه متاحة من أيٍ من الطرفين. ولا يمكن إدراجها في transferList.

قد لا يزال value يحتوي على مثيلات ArrayBuffer غير الموجودة في transferList؛ في هذه الحالة تنسخ الذاكرة الأساسية بدلًا من نقلها.

لان استنساخ الكائن يستخدم خوارزمية الاستنساخ المُهيكَلة، لا يحتفظ بالخصائص غير القابلة للعد، ومُوصِّلات الخاصية (property accessors)، والنماذج الأولية للكائن. علي وجه الخصوص، ستُقرأ كائنات Buffer على أنها Uint8Arrays عادية عند الطرف المُتلقِّي.

سيُستنسخ الكائن message فورًا، ويمكن تعديله بعد النشر دون وجود تأثيرات جانبية.

للحصول علي مزيد من المعلومات حول آليات التسلسل وإلغاء التسلسل من وراء هذه الـ API، راجع واجهات تطبيق التسلسل في الوحدة v8.

port.ref()‎

أضيف مع الإصدار: v10.5.0.

مقابل unref()‎. استدعاء ref()‎ على منفذ سبق إجراء unref عليه لن يسمح للبرنامج بالانتهاء إذا كان هو المعالج الوحيد المتبقي (السلوك الافتراضي). استدعاء ref()‎ مرة أخرى على منفذ سبق إجراء ref عليه لن يكون له أي تأثير.

إذا كان المستمعون متصلين أو أزيلوا باستخدام ‎.on('message')‎، سيُطبق على المنفذ التوابع ref()‎ و unref()‎‎ تلقائيًا اعتمادًا علي وجود مستمعين للحدث.

port.start()‎

أضيف مع الإصدار: v10.5.0.

بدء تلقي الرسائل علي MessagePort هذا. عند استخدام هذا المنفذ كمُطلِق للحدث، سيُستدعى هذا التابع تلقائيًا بمجرد إرفاق مستمعي الحدث 'message'.

port.unref()‎

أضيف مع الإصدار: v10.5.0.

يسمح استدعاء unref()‎ على منفذ للخيط بالإنهاء إذا كان هو المعالج النشط الوحيد في نظام الأحداث. استدعاء unref()‎ مرة أخرى على منفذ سبق إجراء unref عليه لن يكون له أي تأثير.

إذا كان المستمعون متصلين أو أُزيلوا باستخدام ‎.on('message')‎، سيُطبق على المنفذ التوابع ref()‎ و unref()‎‎ تلقائيًا اعتمادًا علي وجود مستمعين للحدث.

الصنف Worker

أضيف مع الإصدار: v10.5.0.

يمثل الصنف Worker خيط تنفيذ JavaScript مستقل. تتوفر معظم واجهات تطبيقات Node.js داخله.

ومن أبرز هذه الاختلافات داخل بيئة Worker:

  • قد يُعاد توجيه process.stdin و process.stdout و process.stderr بواسطة الخيط الأصل.
  • تُضبط الخاصية require('worker_threads').isMainThread بالقيمة false.
  • يصبح منفذ الرسالة require('worker_threads').parentPort متاحًا،
  • ولا يوقف التابعُ process.exit()‎ البرنامجَ بأكمله، فقط الخيطَ منفردًا، ولا يُتاح process.abort()‎.
  • ولا يُتاح process.chdir()‎ ولا توابع العمليات التي تضبط مُعرِّفات المجموعة أو المستخدم.
  • process.env هو مرجع للقراءة فقط إلى متغيرات البيئة.
  • لا يمكن تعديل process.title.
  • لن تُسلَّم الإشارات من خلال process.on('...')‎‎.
  • قد يتوقف التنفيذ عند أي نقطة نتيجة لاستدعاء التابع worker.terminate()‎.
  • لا يمكن الوصول إلى قنوات IPC من العمليات الأصلية.

وتوجد حاليًا الاختلافات التالية أيضا، إلى أن يتم معالجتها:

  • وحده inspector غير مُتاحة حتى الآن.
  • الإضافات الأصلية غير مدعومة حتى الآن.

يمكن إنشاء مثيلات Worker داخل Worker آخرين.

مثلما هو الحال مع Web Workers ووحدة cluster، يمكن تحقيق الاتصالات في اتجاهين من خلال تمرير الرسائل بين الخيوط. يحتوي Worker داخليَا على زوج مُضمَّن من MessagePorts المقترن بالفعل مع بعضه البعض عند إنشاء الكائن Worker. في حين لا يكون الكائن MessagePort علي جانب الأصل مُستهدَفًا بشكل مباشر، تكون وظائفه مُستهدَفة من خلال التابع worker.postMessage()‎ والحدث worker.on('message')‎ علي الكائن Worker لخيط الأصل.

لإنشاء قنوات المراسلة المخصصة (والتي يُفضَّل استخدامها عن استخدام القناة العامة الافتراضية لأنها تُسهِّل فصل الاهتمامات)، يمكن للمستخدمين إنشاء كائن MessageChannel علي أي خيط وتمرير أحد MessagePorts علي هذه MessageChannel إلى الخيط الآخر من خلال قناة موجودة من قبل، مثل القناة العامة.

راجع port.postMessage()‎ للحصول علي مزيد من المعلومات حول كيفية تمرير الرسائل، وماهية نوع قيم JavaScript التي يمكن نقلها بنجاح عبر حاجز الخيط.

const assert = require('assert');
const {
  Worker, MessageChannel, MessagePort, isMainThread, parentPort
} = require('worker_threads');
if (isMainThread) {
  const worker = new Worker(__filename);
  const subChannel = new MessageChannel();
  worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]);
  subChannel.port2.on('message', (value) => {
    console.log('received:', value);
  });
} else {
  parentPort.once('message', (value) => {
    assert(value.hereIsYourPort instanceof MessagePort);
    value.hereIsYourPort.postMessage('يرسل العامل هذا');
    value.hereIsYourPort.close();
  });
}
new Worker(filename[, options])‎

filename من النوع <string>، وهو المسار إلى سكريبت Worker الرئيسي. يجب أن يكون إمَّا مسارًا مطلقًا أو مسارًا نسبيًا (أي بالنسبة إلى دليل العمل الحالي) بدءًا من ‎./‎ أو ‎../‎. إذا كانت options.eval قيمتها true، تكون هذه سلسلة نصية تحتوي علي شيفرة JavaScript بدلًا من المسار.

options من النوع <Object>.

  • eval من النوع <boolean>، إذا كان true، تفسر الوسيط الأول للمُنشئ كسكريبت يُنفَّذ فور اتصال العامل.
  • workerdata من أي نوع من الأنواع <any>، أي قيمة JavaScript ستُستنسَخ وتصبح متاحة في الصورة require('worker_threads').workerData. سيحدث الاستنساخ كما هو موضح في خوارزمية استنساخ HTML المُهيكَلة، وسينطلق خطأ إذا كان لا يمكن استنساخ الكائن (علي سبيل المثال لأنه يحتوي علي دوال).
  • stdin من النوع <boolean>، إذا ضُبط بالقيمة true، سيوفر worker.stdin دفق قابل للكتابة والذي تظهر محتوياته كـ process.stdin داخل Worker. بشكل افتراضي، لا تتوفر أي بيانات.
  • stdout من النوع <boolean>، إذا ضُبط بالقيمة true، لن يُوجَّه worker.stdout تلقائيًا من خلاله إلى process.stdout في الأصل.
  • stderr من النوع <boolean>، إذا ضُبط بالقيمة true، لن يُوجَّه worker.stderr تلقائيًا من خلاله إلى process.stderr في الأصل.

الحدث 'error'

أضيف مع الإصدار: v10.5.0.

سينطلق الحدث 'error' إذا أجرى الخيط العامل استثناءً غير مُلتقَط. في هذه الحالة، سيتم إنهاء العامل.

الحدث 'exit'

أضيف مع الإصدار: v10.5.0.

ينطلق الحدث 'exit' بمجرد توقف العامل. إذا أٌُنهي العامل باستدعاء process.exit()‎، سيكون المعامل exitCode هو رمز الإنهاء الذي مُرِر. إذا أُنهي العامل، سيكون المعامل exitCode قيمته 1.

الحدث 'message'

أضيف مع الإصدار: v10.5.0.

  • value من أي نوع من الأنواع <any>. وهو القيمة المُرسَلة.

ينطلق الحدث 'message' عند استدعاء الخيط العامل للتابع require('worker_threads').postMessage()‎. راجع الحدث port.on('message')‎ للحصول علي مزيد من التفاصيل.

الحدث 'online'

أضيف مع الإصدار: v10.5.0.

ينطلق الحدث 'online' عند بدء الخيط العامل في تنفيذ شيفرة JavaScript البرمجية.

worker.postMessage(value[, transferList])‎

أضيف مع الإصدار: v10.5.0.

  • value من أي نوع من الأنواع <any>.
  • transferList من النوع ‎<Object[]>‎.

إرسال رسالة للعامل يستلمها من خلال require('worker_threads').parentPort.on('message')‎. راجع port.postMessage()‎ للحصول علي مزيد من التفاصيل.

worker.ref()‎

أضيف مع الإصدار: v10.5.0.

على عكس unref()‎، استدعاء ref()‎ على عامل سبق إجراء unref عليه لن يسمح للبرنامج بالانتهاء إذا كان هو المُعالج الوحيد المتبقي (السلوك الافتراضي). استدعاء ref()‎ مرة أخرى على عامل سبق إجراء ref عليه لن يكون له أي تأثير.

worker.stderr

أضيف مع الإصدار: v10.5.0.

وهو دفق قابل للقراءة يحتوي علي البيانات المكتوبة على process.stderr داخل خيط العامل. إذا لم تُمرر stderr: true لمُنشِئ Worker، ستُوجَّه البيانات إلى دفق process.stderr لخيط الأصل.

worker.stdin

أضيف مع الإصدار: v10.5.0.

إذا مُررت stdin: true لمُنشِئ Worker، يكون ذلك دفق قابل للكتابة. ستُتاح البيانات المكتوبة إلى دفق process.stdin في الخيط العامل.

worker.stdout

أضيف مع الإصدار: v10.5.0.

وهو دفق قابل للقراءة يحتوي علي البيانات المكتوبة على process.stdout داخل خيط العامل. إذا مُررت stdout: true لمُنشِئ Worker، ستوجه البيانات إلى دفق process.stdout لخيط الأصل.

worker.terminate([callback])‎

أضيف مع الإصدار: v10.5.0.

إيقاف تنفيذ كافة JavaScript في الخيط العامل في أقرب وقت ممكن. callback هو دالة اختيارية تُستدعى بمجرد معرفة اكتمال هذه العملية.

تحذير: حاليًا، ليست جميع الشيفرات البرمجية الداخلية في Node.js مستعدة لتوقع الإنهاء في نقاط عشوائية في الوقت المناسب وقد يتلف إذا واجه هذا الظرف. وبناءً على لذلك، يجب حاليًا فقط استدعاء ‎.terminate()‎ إذا كان من المعروف أن الخيط العامل لا يمكنه الوصول إلى الوحدات الأساسية من Node.js غير المعروض في وحدة العامل.

worker.threadId

أضيف مع الإصدار: v10.5.0.

عدد صحيح مُعرِّف للخيط المشار إليه. داخل الخيط العامل، ويكون متوفرًا في الصورة require('worker_threads').threadId.

worker.unref()‎

أضيف مع الإصدار: v10.5.0.

يسمح استدعاء unref()‎ على عامل للخيط بالإنهاء إذا كان هو المعالج النشط الوحيد في نظام الأحداث. استدعاء unref()‎ مرة أخرى على عامل سبق إجراء unref عليه لن يكون له أي تأثير.

مصادر