Skip to content

مؤشرات العمل

[مستقر: 2 - مستقر]

مستقر: 2 ثبات: 2 - مستقر

رمز المصدر: lib/worker_threads.js

تمكّن وحدة node:worker_threads من استخدام مؤشرات تُنفذ جافا سكريبت بالتوازي. للوصول إليها:

js
const worker = require('node:worker_threads')

تُعد مؤشرات العمل (الخيوط) مفيدة لأداء عمليات جافا سكريبت كثيفة الحساب. لا تساعد كثيرًا في العمل المكثف لإدخال/إخراج البيانات. عمليات إدخال/إخراج البيانات غير المتزامنة المُدمجة في Node.js أكثر كفاءة مما يمكن أن تكون عليه مؤشرات العمل.

على عكس child_process أو cluster، يمكن لمؤشرات worker_threads مشاركة الذاكرة. تفعل ذلك عن طريق نقل مثيلات ArrayBuffer أو مشاركة مثيلات SharedArrayBuffer.

js
const { Worker, isMainThread, parentPort, workerData } = require('node:worker_threads')

if (isMainThread) {
  module.exports = 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))
}

يُنشئ المثال أعلاه مؤشر عمل لكل مُدعاء parseJSAsync(). في الممارسة العملية، استخدم مجموعة من مؤشرات العمل لهذه الأنواع من المهام. خلاف ذلك، من المرجح أن يتجاوز عبء إنشاء مؤشرات العمل فائدتها.

عند تنفيذ مجموعة من مؤشرات العمل، استخدم واجهة برمجة التطبيقات AsyncResource لإبلاغ أدوات التشخيص (مثلًا لتوفير تتبعات المكدس غير المتزامنة) حول الارتباط بين المهام ونتائجها. انظر "استخدام AsyncResource لمجموعة مؤشرات عمل Worker" في وثائق async_hooks للحصول على مثال على التنفيذ.

تورث مؤشرات العمل الخيارات غير الخاصة بالعملية افتراضيًا. راجع خيارات مُنشئ Worker لمعرفة كيفية تخصيص خيارات مؤشر العمل، وتحديدًا خيارات argv و execArgv.

worker.getEnvironmentData(key)

[السجل]

الإصدارالتغييرات
v17.5.0, v16.15.0لم يعد تجريبيًا.
v15.12.0, v14.18.0تمت الإضافة في: v15.12.0, v14.18.0
  • key <أي> أي قيمة JavaScript تعسفية قابلة للاستنساخ يمكن استخدامها كمفتاح <Map>.
  • القيمة المُرجعة: <أي>

ضمن مؤشر ترابط عامل، تُرجع worker.getEnvironmentData() نسخةً مستنسخة من البيانات المُمررة إلى مؤشر ترابط إنشاء مؤشر الترابط worker.setEnvironmentData(). يتلقى كل Worker جديد نسخةً خاصة به من بيانات البيئة تلقائيًا.

js
const { Worker, isMainThread, setEnvironmentData, getEnvironmentData } = require('node:worker_threads')

if (isMainThread) {
  setEnvironmentData('Hello', 'World!')
  const worker = new Worker(__filename)
} else {
  console.log(getEnvironmentData('Hello')) // يُطبع 'World!'.
}

worker.isMainThread

تمت الإضافة في: v10.5.0

تكون true إذا لم يتم تشغيل هذا الكود داخل مؤشر ترابط Worker.

js
const { Worker, isMainThread } = require('node:worker_threads')

if (isMainThread) {
  // هذا يعيد تحميل الملف الحالي داخل مثيل عامل.
  new Worker(__filename)
} else {
  console.log('Inside Worker!')
  console.log(isMainThread) // يُطبع 'false'.
}

worker.markAsUntransferable(object)

تمت الإضافة في: v14.5.0, v12.19.0

  • object <أي> أي قيمة JavaScript تعسفية.

ضع علامة على كائن بأنه غير قابل للتحويل. إذا حدث object في قائمة النقل لـ port.postMessage()، فسيتم إرجاع خطأ. هذه عملية لا شيء إذا كانت object قيمة بدائية.

على وجه الخصوص، هذا منطقي للأشياء التي يمكن استنساخها، بدلاً من نقلها، والتي تُستخدم بواسطة كائنات أخرى على جانب الإرسال. على سبيل المثال، يُشير Node.js إلى مجموعات ArrayBuffer التي يستخدمها لمجموعة Buffer باستخدام هذا.

لا يمكن التراجع عن هذه العملية.

js
const { MessageChannel, markAsUntransferable } = require('node:worker_threads')

const pooledBuffer = new ArrayBuffer(8)
const typedArray1 = new Uint8Array(pooledBuffer)
const typedArray2 = new Float64Array(pooledBuffer)

markAsUntransferable(pooledBuffer)

const { port1 } = new MessageChannel()
try {
  // هذا سيرمي خطأ، لأن pooledBuffer غير قابل للتحويل.
  port1.postMessage(typedArray1, [typedArray1.buffer])
} catch (error) {
  // error.name === 'DataCloneError'
}

// يطبع السطر التالي محتويات typedArray1 -- لا يزال يمتلك
// ذاكرته ولم يتم نقله. بدون
// `markAsUntransferable()`، سيطبع هذا Uint8Array فارغًا وسوف تنجح
// مكالمة postMessage.
// typedArray2 سليم أيضًا.
console.log(typedArray1)
console.log(typedArray2)

لا يوجد ما يعادل هذا الـ API في المتصفحات.

worker.isMarkedAsUntransferable(object)

مضاف في: v21.0.0

  • object <any> أي قيمة جافا سكريبت.
  • قيمة الإرجاع: <boolean>

التحقق مما إذا كان الكائن مُعيّنًا على أنه غير قابل للتحويل باستخدام markAsUntransferable().

js
const { markAsUntransferable, isMarkedAsUntransferable } = require('node:worker_threads')

const pooledBuffer = new ArrayBuffer(8)
markAsUntransferable(pooledBuffer)

isMarkedAsUntransferable(pooledBuffer) // تُعيد true.

لا يوجد ما يعادل هذا التطبيق البرمجي في المتصفحات.

worker.markAsUncloneable(object)

مضاف في: v23.0.0

  • object <any> أي قيمة جافا سكريبت تعسفية.

تعيين كائن على أنه غير قابل للاستنساخ. إذا تم استخدام object كـ message في مكالمة port.postMessage()، فسيتم إرسال خطأ. هذه عملية لا تؤثر إذا كانت object قيمة بدائية.

ليس لهذا أي تأثير على ArrayBuffer، أو أي كائنات مشابهة لـ Buffer.

لا يمكن التراجع عن هذه العملية.

js
const { markAsUncloneable } = require('node:worker_threads')

const anyObject = { foo: 'bar' }
markAsUncloneable(anyObject)
const { port1 } = new MessageChannel()
try {
  // هذا سيُرسل خطأ، لأن anyObject غير قابل للاستنساخ.
  port1.postMessage(anyObject)
} catch (error) {
  // error.name === 'DataCloneError'
}

لا يوجد ما يعادل هذا التطبيق البرمجي في المتصفحات.

worker.moveMessagePortToContext(port, contextifiedSandbox)

مضاف في: v11.13.0

تحويل MessagePort إلى سياق vm مختلف. يصبح كائن port الأصلي غير قابل للاستخدام، ويحل محلّه مثيل MessagePort المُرجَع.

MessagePort المُرجَع هو كائن في السياق الهدف ويرث من فئة Object العالمية الخاصة به. يتم أيضًا إنشاء الكائنات الممررة إلى المُستمع port.onmessage() في السياق الهدف ويرث من فئة Object العالمية الخاصة به.

ومع ذلك، فإن MessagePort المُنشأ لم يعد يرث من EventTarget، و يمكن فقط استخدام port.onmessage() لاستقبال الأحداث باستخدامها.

worker.parentPort

مضاف في: v10.5.0

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

js
const { Worker, isMainThread, parentPort } = require('node:worker_threads')

if (isMainThread) {
  const worker = new Worker(__filename)
  worker.once('message', message => {
    console.log(message) // يطبع 'Hello, world!'.
  })
  worker.postMessage('Hello, world!')
} else {
  // عند استقبال رسالة من الخيط الرئيسي، أرسلها مرة أخرى:
  parentPort.once('message', message => {
    parentPort.postMessage(message)
  })
}

worker.postMessageToThread(threadId, value[, transferList][, timeout])

مضاف في: v22.5.0

[مستقر: 1 - تجريبي]

مستقر: 1 استقرار: 1.1 - تطوير نشط

  • threadId <number> معرف الخيط الهدف. إذا كان معرف الخيط غير صالح، فسيتم إرسال خطأ ERR_WORKER_MESSAGING_FAILED. إذا كان معرف الخيط الهدف هو معرف الخيط الحالي، فسيتم إرسال خطأ ERR_WORKER_MESSAGING_SAME_THREAD.
  • value <any> القيمة المراد إرسالها.
  • transferList <Object[]> إذا تم تمرير كائن واحد أو أكثر من نوع MessagePort في value، يلزم وجود transferList لتلك العناصر أو يتم إرسال خطأ ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST. راجع port.postMessage() لمزيد من المعلومات.
  • timeout <number> وقت الانتظار لإرسال الرسالة بالميلي ثانية. افتراضيًا، يكون undefined، مما يعني الانتظار إلى الأبد. إذا انتهى وقت العملية، فسيتم إرسال خطأ ERR_WORKER_MESSAGING_TIMEOUT.
  • الإرجاع: <Promise> وعد يتم تنفيذه إذا تم معالجة الرسالة بنجاح بواسطة خيط الوجهة.

يرسل قيمة إلى عامل آخر، يتم تحديده بواسطة معرف الخيط الخاص به.

إذا لم يكن للخيط الهدف مستمع لحدث workerMessage، فستقوم العملية بإرسال خطأ ERR_WORKER_MESSAGING_FAILED.

إذا ألقى الخيط الهدف خطأً أثناء معالجة حدث workerMessage، فستقوم العملية بإرسال خطأ ERR_WORKER_MESSAGING_ERRORED.

يجب استخدام هذه الطريقة عندما لا يكون الخيط الهدف هو الأصل أو الفرع المباشر للخيط الحالي. إذا كان الخيطان هما الأصل والفرع، فاستخدم require('node:worker_threads').parentPort.postMessage() و worker.postMessage() للسماح للخيوط بالتواصل.

يوضح المثال التالي استخدام postMessageToThread: يقوم بإنشاء 10 خيوط متداخلة، سيحاول الخيط الأخير التواصل مع الخيط الرئيسي.

js
import { fileURLToPath } from 'node:url'
import process from 'node:process'
import { postMessageToThread, threadId, workerData, Worker } from 'node:worker_threads'

const channel = new BroadcastChannel('sync')
const level = workerData?.level ?? 0

if (level < 10) {
  const worker = new Worker(fileURLToPath(import.meta.url), {
    workerData: { level: level + 1 },
  })
}

if (level === 0) {
  process.on('workerMessage', (value, source) => {
    console.log(`${source} -> ${threadId}:`, value)
    postMessageToThread(source, { message: 'pong' })
  })
} else if (level === 10) {
  process.on('workerMessage', (value, source) => {
    console.log(`${source} -> ${threadId}:`, value)
    channel.postMessage('done')
    channel.close()
  })

  await postMessageToThread(0, { message: 'ping' })
}

channel.onmessage = channel.close
js
const { postMessageToThread, threadId, workerData, Worker } = require('node:worker_threads')

const channel = new BroadcastChannel('sync')
const level = workerData?.level ?? 0

if (level < 10) {
  const worker = new Worker(__filename, {
    workerData: { level: level + 1 },
  })
}

if (level === 0) {
  process.on('workerMessage', (value, source) => {
    console.log(`${source} -> ${threadId}:`, value)
    postMessageToThread(source, { message: 'pong' })
  })
} else if (level === 10) {
  process.on('workerMessage', (value, source) => {
    console.log(`${source} -> ${threadId}:`, value)
    channel.postMessage('done')
    channel.close()
  })

  postMessageToThread(0, { message: 'ping' })
}

channel.onmessage = channel.close

worker.receiveMessageOnPort(port)

[السجل]

الإصدارالتغييرات
v15.12.0يمكن الآن أن تشير وسيطة port إلى BroadcastChannel.
v12.3.0تمت الإضافة في: v12.3.0

استقبال رسالة واحدة من MessagePort معين. إذا لم تتوفر أي رسالة، يتم إرجاع undefined، وإلا سيتم إرجاع كائن بخصائص message واحدة تحتوي على حمولة الرسالة، المقابلة لأقدم رسالة في قائمة انتظار MessagePort.

js
const { MessageChannel, receiveMessageOnPort } = require('node:worker_threads')
const { port1, port2 } = new MessageChannel()
port1.postMessage({ hello: 'world' })

console.log(receiveMessageOnPort(port2))
// يطبع: { message: { hello: 'world' } }
console.log(receiveMessageOnPort(port2))
// يطبع: undefined

عندما يتم استخدام هذه الوظيفة، لا يتم إرسال حدث 'message' ولا يتم استدعاء مُستمع onmessage.

worker.resourceLimits

تمت الإضافة في: v13.2.0، v12.16.0

يوفر مجموعة من قيود موارد محرك JS داخل مؤشر ترابط هذا العامل. إذا تم تمرير خيار resourceLimits إلى مُنشئ Worker، فإنه يطابق قيمه.

إذا تم استخدام هذا في الخيط الرئيسي، فإن قيمته هي كائن فارغ.

worker.SHARE_ENV

مضاف في: v11.14.0

قيمة خاصة يمكن تمريرها كخيار env لباني Worker ، للإشارة إلى أن الخيط الحالي وخيط عامل التشغيل يجب أن يتشاركا في الوصول للقراءة والكتابة إلى نفس مجموعة متغيرات البيئة.

js
const { Worker, SHARE_ENV } = require('node:worker_threads')
new Worker('process.env.SET_IN_WORKER = "foo"', { eval: true, env: SHARE_ENV }).on('exit', () => {
  console.log(process.env.SET_IN_WORKER) // يطبع 'foo'.
})

worker.setEnvironmentData(key[, value])

[السجل]

الإصدارالتغييرات
v17.5.0, v16.15.0لم يعد تجريبيًا.
v15.12.0, v14.18.0مضاف في: v15.12.0, v14.18.0
  • key <any> أي قيمة جافا سكريبت تعسفية قابلة للاستنساخ يمكن استخدامها كمفتاح <Map>.
  • value <any> أي قيمة جافا سكريبت تعسفية قابلة للاستنساخ سيتم استنساخها ومرورها تلقائيًا إلى جميع مثيلات Worker الجديدة. إذا تم تمرير value كـ undefined، فسيتم حذف أي قيمة تم تعيينها مسبقًا للمفتاح key.

يقوم واجهة برمجة التطبيقات worker.setEnvironmentData() بتعيين محتوى worker.getEnvironmentData() في الخيط الحالي وجميع مثيلات Worker الجديدة التي تم إنشاؤها من السياق الحالي.

worker.threadId

مضاف في: v10.5.0

معرف رقمي للخيط الحالي. في كائن عامل التشغيل المقابل (إن وجد) ، يكون متاحًا كـ worker.threadId. هذه القيمة فريدة لكل مثيل Worker داخل عملية واحدة.

worker.workerData

مضاف في: v10.5.0

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

يتم استنساخ البيانات كما لو كانت تستخدم postMessage()، وفقًا لخوارزمية الاستنساخ المُبنيّة HTML.

js
const { Worker, isMainThread, workerData } = require('node:worker_threads')

if (isMainThread) {
  const worker = new Worker(__filename, { workerData: 'Hello, world!' })
} else {
  console.log(workerData) // يطبع 'Hello, world!'.
}

Class: BroadcastChannel extends EventTarget

[History]

الإصدارالتغييرات
v18.0.0لم يعد تجريبيًا.
v15.4.0مضاف في: v15.4.0

تسمح مثيلات BroadcastChannel بالتواصل غير المتزامن من واحد إلى العديد مع جميع مثيلات BroadcastChannel الأخرى المرتبطة بنفس اسم القناة.

js
'use strict'

const { isMainThread, BroadcastChannel, Worker } = require('node:worker_threads')

const bc = new BroadcastChannel('hello')

if (isMainThread) {
  let c = 0
  bc.onmessage = event => {
    console.log(event.data)
    if (++c === 10) bc.close()
  }
  for (let n = 0; n < 10; n++) new Worker(__filename)
} else {
  bc.postMessage('hello from every worker')
  bc.close()
}

new BroadcastChannel(name)

مضاف في: v15.4.0

  • name <أي> اسم القناة للاتصال بها. أي قيمة JavaScript يمكن تحويلها إلى سلسلة باستخدام ${name} مسموح بها.

broadcastChannel.close()

مضاف في: v15.4.0

يغلق اتصال BroadcastChannel.

broadcastChannel.onmessage

مضاف في: v15.4.0

  • النوع: <Function> يتم استدعاؤه باستخدام وسيطة MessageEvent واحدة عند استقبال رسالة.

broadcastChannel.onmessageerror

تم الإضافة في: v15.4.0

  • النوع: <Function> يتم استدعاء هذه الدالة عندما لا يمكن فك تسلسل الرسالة المستلمة.

broadcastChannel.postMessage(message)

تم الإضافة في: v15.4.0

  • message <any> أي قيمة JavaScript قابلة للاستنساخ.

broadcastChannel.ref()

تم الإضافة في: v15.4.0

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

broadcastChannel.unref()

تم الإضافة في: v15.4.0

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

الفئة: MessageChannel

تم الإضافة في: v10.5.0

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

js
const { MessageChannel } = require('node:worker_threads')

const { port1, port2 } = new MessageChannel()
port1.on('message', message => console.log('received', message))
port2.postMessage({ foo: 'bar' })
// يطبع: received { foo: 'bar' } من مُستمع `port1.on('message')`

الفئة: MessagePort

[السجل]

الإصدارالتغييرات
v14.7.0هذه الفئة ترث الآن من EventTarget بدلاً من EventEmitter.
v10.5.0تم الإضافة في: v10.5.0

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

يتوافق هذا التنفيذ مع متصفح MessagePorts.

حدث: 'close'

مضاف في: v10.5.0

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

js
const { MessageChannel } = require('node:worker_threads')
const { port1, port2 } = new MessageChannel()

// يطبع:
//   foobar
//   closed!
port2.on('message', message => console.log(message))
port2.on('close', () => console.log('closed!'))

port1.postMessage('foobar')
port1.close()

حدث: 'message'

مضاف في: v10.5.0

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

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

حدث: 'messageerror'

مضاف في: v14.5.0، v12.19.0

يتم بث حدث 'messageerror' عندما يفشل إلغاء تسلسل الرسالة.

حاليًا، يتم بث هذا الحدث عندما يحدث خطأ أثناء إنشاء كائن JS المُرسل في الطرف المُستقبِل. مثل هذه الحالات نادرة، ولكن يمكن أن تحدث، على سبيل المثال، عند استلام كائنات واجهة برمجة تطبيقات Node.js معينة في vm.Context (حيث تتوفر واجهات برمجة تطبيقات Node.js حاليًا).

port.close()

مضاف في: v10.5.0

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

يتم بث حدث 'close' على كلا مثالي MessagePort اللذين هما جزء من القناة.

port.postMessage(value[, transferList])

[السجل]

الإصدارالتغييرات
v21.0.0يتم إرسال خطأ عند وجود كائن غير قابل للتحويل في قائمة التحويل.
v15.6.0تمت إضافة X509Certificate إلى قائمة الأنواع القابلة للاستنساخ.
v15.0.0تمت إضافة CryptoKey إلى قائمة الأنواع القابلة للاستنساخ.
v15.14.0، v14.18.0إضافة 'BlockList' إلى قائمة الأنواع القابلة للاستنساخ.
v15.9.0، v14.18.0إضافة أنواع 'Histogram' إلى قائمة الأنواع القابلة للاستنساخ.
v14.5.0، v12.19.0تمت إضافة KeyObject إلى قائمة الأنواع القابلة للاستنساخ.
v14.5.0، v12.19.0تمت إضافة FileHandle إلى قائمة الأنواع القابلة للتحويل.
v10.5.0مضاف في: v10.5.0

يرسل قيمة JavaScript إلى الطرف المُستقبِل لهذه القناة. يتم نقل value بطريقة تتوافق مع خوارزمية الاستنساخ المُبنيّة HTML.

على وجه الخصوص، الاختلافات المهمة مع JSON هي:

js
const { MessageChannel } = require('node:worker_threads')
const { port1, port2 } = new MessageChannel()

port1.on('message', message => console.log(message))

const circularData = {}
circularData.foo = circularData
// يطبع: { foo: [Circular] }
port2.postMessage(circularData)

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

إذا كان value يحتوي على حالات من SharedArrayBuffer، فإن هذه الحالات قابلة للوصول من أي خيط. لا يمكن إدراجها في transferList.

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

js
const { MessageChannel } = require('node:worker_threads')
const { port1, port2 } = new MessageChannel()

port1.on('message', message => console.log(message))

const uint8Array = new Uint8Array([1, 2, 3, 4])
// هذا ينشر نسخة من `uint8Array`:
port2.postMessage(uint8Array)
// هذا لا ينسخ البيانات، ولكنه يجعل `uint8Array` غير قابل للاستخدام:
port2.postMessage(uint8Array, [uint8Array.buffer])

// الذاكرة الخاصة بـ `sharedUint8Array` قابلة للوصول من الأصل والنسخة المُستقبلة بواسطة `.on('message')`:
const sharedUint8Array = new Uint8Array(new SharedArrayBuffer(4))
port2.postMessage(sharedUint8Array)

// هذا ينقل منفذ رسالة تم إنشاؤه حديثًا إلى المُستقبِل.
// يمكن استخدام هذا، على سبيل المثال، لإنشاء قنوات اتصال بين
// العديد من خيوط `Worker` التي هي أطفال لنفس الخيط الرئيسي.
const otherChannel = new MessageChannel()
port2.postMessage({ port: otherChannel.port1 }, [otherChannel.port1])

يتم استنساخ كائن الرسالة على الفور، ويمكن تعديله بعد النشر دون وجود آثار جانبية.

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

اعتبارات عند نقل TypedArrays و Buffers

جميع مثيلات TypedArray و Buffer هي عروض على ArrayBuffer أساسي. أي أن ArrayBuffer هو الذي يخزن البيانات الخام بالفعل بينما توفر كائنات TypedArray و Buffer طريقة لعرض البيانات وتلاعبها. من الممكن والشيء الشائع إنشاء عروض متعددة على نفس مثيل ArrayBuffer. يجب توخي الحذر الشديد عند استخدام قائمة النقل لنقل ArrayBuffer لأن القيام بذلك يتسبب في عدم إمكانية استخدام جميع مثيلات TypedArray و Buffer التي تشترك في نفس ArrayBuffer.

js
const ab = new ArrayBuffer(10)

const u1 = new Uint8Array(ab)
const u2 = new Uint16Array(ab)

console.log(u2.length) // يطبع 5

port.postMessage(u1, [u1.buffer])

console.log(u2.length) // يطبع 0

بالنسبة لمعظم مثيلات Buffer، يعتمد ما إذا كان بإمكان نقل أو استنساخ ArrayBuffer الأساسي كليًا على كيفية إنشاء المثيلات، والتي غالبًا ما لا يمكن تحديدها بشكل موثوق.

يمكن تمييز ArrayBuffer باستخدام markAsUntransferable() للإشارة إلى أنه يجب دائمًا استنساخه وعدم نقله أبدًا.

اعتمادًا على كيفية إنشاء مثيل Buffer، فقد يمتلك أو لا يمتلك ArrayBuffer الأساسي الخاص به. يجب عدم نقل ArrayBuffer إلا إذا كان معروفًا أن مثيل Buffer يمتلكه. على وجه الخصوص، بالنسبة لـ Buffers التي تم إنشاؤها من مجموعة Buffer الداخلية (باستخدام، على سبيل المثال Buffer.from() أو Buffer.allocUnsafe())، لا يمكن نقلها ويتم دائمًا استنساخها، مما يرسل نسخة من مجموعة Buffer بأكملها. قد يأتي هذا السلوك مع استخدام ذاكرة أعلى غير مقصود ومخاوف أمنية محتملة.

انظر Buffer.allocUnsafe() لمزيد من التفاصيل حول تجميع Buffer.

يمكن دائمًا نقل ArrayBuffers لمعظم مثيلات Buffer التي تم إنشاؤها باستخدام Buffer.alloc() أو Buffer.allocUnsafeSlow()، ولكن القيام بذلك يجعل جميع العروض الأخرى الموجودة لـ ArrayBuffers هذه غير قابلة للاستخدام.

اعتبارات عند استنساخ الكائنات باستخدام النماذج الأولية، والفئات، وواجهات الوصول

بما أن استنساخ الكائنات يستخدم خوارزمية الاستنساخ المنظم HTML، فإن الخصائص غير القابلة للعد، وواجهات الوصول للخصائص، ونماذج الكائنات الأولية لا يتم الاحتفاظ بها. على وجه الخصوص، سيتم قراءة كائنات Buffer كـ Uint8Array عادية على الجانب المستلم، وسيتم استنساخ مثيلات فئات JavaScript كائنات JavaScript عادية.

js
const b = Symbol('b')

class Foo {
  #a = 1
  constructor() {
    this[b] = 2
    this.c = 3
  }

  get d() {
    return 4
  }
}

const { port1, port2 } = new MessageChannel()

port1.onmessage = ({ data }) => console.log(data)

port2.postMessage(new Foo())

// يطبع: { c: 3 }

يُمتد هذا القيد إلى العديد من الكائنات المضمنة، مثل كائن URL العالمي:

js
const { port1, port2 } = new MessageChannel()

port1.onmessage = ({ data }) => console.log(data)

port2.postMessage(new URL('https://example.org'))

// يطبع: { }

port.hasRef()

مضاف في: v18.1.0، v16.17.0

[مستقر: 1 - تجريبي]

مستقر: 1 ثبات: 1 - تجريبي

إذا كانت القيمة صحيحة، فسوف يحتفظ كائن MessagePort بحلقة أحداث Node.js نشطة.

port.ref()

مضاف في: v10.5.0

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

إذا تم إرفاق المُستمعين أو إزالتهم باستخدام .on('message')، فسيتم عمل مرجع للمنفذ وإلغاء مرجعه تلقائيًا بناءً على ما إذا كانت المُستمعين للحدث موجودين أم لا.

port.start()

مضاف في: v10.5.0

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

توجد هذه الطريقة لمطابقة واجهة برمجة تطبيقات MessagePort على الويب. في Node.js، إنها مفيدة فقط لتجاهل الرسائل عندما لا يكون هناك مستمع للأحداث. يختلف Node.js أيضًا في طريقة معالجته لـ.onmessage. يؤدي تعيينه إلى استدعاء .start() تلقائيًا، لكن إلغاؤه يسمح بتكدس الرسائل حتى يتم تعيين مُعالِج جديد أو يتم تجاهل المنفذ.

port.unref()

مضاف في: v10.5.0

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

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

الصف: Worker

مضاف في: v10.5.0

يمثل فصل Worker مؤشرًا على مؤشر تنفيذ جافا سكريبت مستقل. تتوفر معظم واجهات برمجة تطبيقات Node.js بداخله.

الاختلافات الملحوظة داخل بيئة Worker هي:

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

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

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

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

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

js
const assert = require('node:assert')
const { Worker, MessageChannel, MessagePort, isMainThread, parentPort } = require('node: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('the worker is sending this')
    value.hereIsYourPort.close()
  })
}

new Worker(filename[, options])

[History]

الإصدارالتغييرات
v19.8.0, v18.16.0تمت إضافة دعم لخيار name، والذي يسمح بإضافة اسم إلى عنوان عامل التشغيل لأغراض التصحيح.
v14.9.0يمكن أن يكون المعامل filename كائن URL من WHATWG باستخدام بروتوكول data: .
v14.9.0تم تعيين خيار trackUnmanagedFds على true افتراضيًا.
v14.6.0, v12.19.0تم تقديم خيار trackUnmanagedFds.
v13.13.0, v12.17.0تم تقديم خيار transferList.
v13.12.0, v12.17.0يمكن أن يكون المعامل filename كائن URL من WHATWG باستخدام بروتوكول file: .
v13.4.0, v12.16.0تم تقديم خيار argv.
v13.2.0, v12.16.0تم تقديم خيار resourceLimits.
v10.5.0تمت الإضافة في: v10.5.0
  • filename <string> | <URL> المسار إلى البرنامج النصي الرئيسي أو الوحدة النمطية لـ Worker. يجب أن يكون إما مسارًا مطلقًا أو مسارًا نسبيًا (أي نسبيًا إلى دليل العمل الحالي) يبدأ بـ ./ أو ../، أو كائن URL من WHATWG باستخدام بروتوكول file: أو data: . عند استخدام عنوان URL من نوع data:، يتم تفسير البيانات بناءً على نوع MIME باستخدام محمل الوحدات النمطية ECMAScript. إذا كان options.eval يساوي true، فهذا سلسلة تحتوي على رمز JavaScript بدلاً من مسار.

  • options <Object>

    • argv <any[]> قائمة بالوسائط التي سيتم تحويلها إلى سلسلة وإلحاقها بـ process.argv في عامل التشغيل. هذا مشابه جدًا لـ workerData، لكن القيم متاحة على process.argv العالمي كما لو تم تمريرها كخيارات CLI إلى البرنامج النصي.

    • env <Object> إذا تم تعيينه، فيحدد القيمة الأولية لـ process.env داخل مؤشر ترابط عامل التشغيل. كقيمة خاصة، يمكن استخدام worker.SHARE_ENV لتحديد أن مؤشر الترابط الرئيسي ومؤشر الترابط الفرعي يجب أن يتشاركا متغيرات بيئتهما؛ في هذه الحالة، تؤثر التغييرات التي تطرأ على كائن process.env في أحد الخيوط على الخيط الآخر أيضًا. افتراضيًا: process.env.

    • eval <boolean> إذا كان true والمعامل الأول هو string، فقم بتفسير المعامل الأول للمنشئ كبرنامج نصي يتم تنفيذه بمجرد أن يصبح عامل التشغيل متصلاً بالشبكة.

    • execArgv <string[]> قائمة بخيارات سطر أوامر node التي تم تمريرها إلى عامل التشغيل. لا يتم دعم خيارات V8 (مثل --max-old-space-size) والخيارات التي تؤثر على العملية (مثل --title). إذا تم تعيينه، فسيتم توفيره كـ process.execArgv داخل عامل التشغيل. افتراضيًا، يتم توريث الخيارات من مؤشر الترابط الرئيسي.

    • stdin <boolean> إذا تم تعيين هذا على true، فإن worker.stdin يوفر تيارًا قابلًا للكتابة تظهر محتوياته كـ process.stdin داخل عامل التشغيل. افتراضيًا، لا يتم توفير أي بيانات.

    • stdout <boolean> إذا تم تعيين هذا على true، فلن يتم توجيه worker.stdout تلقائيًا إلى process.stdout في الأصل.

    • stderr <boolean> إذا تم تعيين هذا على true، فلن يتم توجيه worker.stderr تلقائيًا إلى process.stderr في الأصل.

    • workerData <any> أي قيمة JavaScript يتم استنساخها وجعلها متاحة كـ require('node:worker_threads').workerData. يحدث الاستنساخ كما هو موضح في خوارزمية الاستنساخ الهيكلي لـ HTML، ويتم إرسال خطأ إذا تعذر استنساخ الكائن (مثل بسبب احتوائه على functions).

    • trackUnmanagedFds <boolean> إذا تم تعيين هذا على true، فإن عامل التشغيل يتتبع واصفات الملفات الخام المُدارة من خلال fs.open() و fs.close()، ويغلقها عند خروج عامل التشغيل، على غرار الموارد الأخرى مثل مقابس الشبكة أو واصفات الملفات المُدارة من خلال واجهة برمجة التطبيقات FileHandle. يتم توريث هذا الخيار تلقائيًا بواسطة جميع عناصر Worker المتداخلة. افتراضيًا: true.

    • transferList <Object[]> إذا تم تمرير كائن واحد أو أكثر من نوع MessagePort في workerData، يلزم وجود transferList لتلك العناصر أو سيتم إرسال ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST. راجع port.postMessage() لمزيد من المعلومات.

    • resourceLimits <Object> مجموعة اختيارية من حدود الموارد لمثيل محرك JS الجديد. يؤدي الوصول إلى هذه الحدود إلى إنهاء مثيل Worker. هذه الحدود تؤثر فقط على محرك JS، ولا بيانات خارجية، بما في ذلك عدم وجود ArrayBuffers. حتى إذا تم تعيين هذه الحدود، فقد لا تزال العملية تتوقف إذا واجهت حالة ذاكرة خارجية عامة.

    • maxOldGenerationSizeMb <number> الحد الأقصى لحجم الكومة الرئيسية بالميغابايت. إذا تم تعيين وسيطة سطر الأوامر --max-old-space-size، فإنها تتجاوز هذا الإعداد.

    • maxYoungGenerationSizeMb <number> الحد الأقصى لحجم مساحة الكومة للكائنات التي تم إنشاؤها مؤخرًا. إذا تم تعيين وسيطة سطر الأوامر --max-semi-space-size، فإنها تتجاوز هذا الإعداد.

    • codeRangeSizeMb <number> حجم نطاق ذاكرة مُخصص مسبقًا يستخدم للرمز المُولّد.

    • stackSizeMb <number> الحد الأقصى لحجم المكدس الافتراضي للخيط. قد تؤدي القيم الصغيرة إلى عدم إمكانية استخدام مثيلات Worker. افتراضيًا: 4.

    • name <string> اسم اختياري ليتم إلحاقه بعنوان عامل التشغيل لأغراض التصحيح/التعريف، مما يجعل العنوان النهائي كـ [worker ${id}] ${name}. افتراضيًا: ''.

حدث: 'error'

مضاف في: v10.5.0

يتم إصدار حدث 'error' إذا قام مؤشر ترابط عامل بإرسال استثناء غير معالج. في هذه الحالة، يتم إنهاء العامل.

حدث: 'exit'

مضاف في: v10.5.0

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

هذا هو الحدث النهائي الذي يتم إصداره بواسطة أي مثيل Worker.

حدث: 'message'

مضاف في: v10.5.0

  • value <any> القيمة المُرسلة

يتم إصدار حدث 'message' عندما يكون مؤشر ترابط العامل قد استدعى require('node:worker_threads').parentPort.postMessage(). راجع حدث port.on('message') لمزيد من التفاصيل.

يتم إصدار جميع الرسائل المرسلة من مؤشر ترابط العامل قبل إصدار حدث 'exit' على كائن Worker.

حدث: 'messageerror'

مضاف في: v14.5.0، v12.19.0

يتم إصدار حدث 'messageerror' عندما يفشل إلغاء تسلسل رسالة.

حدث: 'online'

مضاف في: v10.5.0

يتم إصدار حدث 'online' عندما يبدأ مؤشر ترابط العامل في تنفيذ رمز JavaScript.

worker.getHeapSnapshot([options])

[السجل]

الإصدارالتغييرات
v19.1.0دعم الخيارات لتكوين لقطة الكومة.
v13.9.0، v12.17.0مضاف في: v13.9.0، v12.17.0
  • options <Object>

    • exposeInternals <boolean> إذا كان صحيحًا، فقم بكشف الأجزاء الداخلية في لقطة الكومة. افتراضيًا: false.
    • exposeNumericValues <boolean> إذا كان صحيحًا، فقم بكشف القيم العددية في الحقول الاصطناعية. افتراضيًا: false.
  • القيمة المُرجعه: <Promise> وعد لبث قابل للقراءة يحتوي على لقطة كومة V8

يرجع دفقًا قابلًا للقراءة للقطة V8 للحالة الحالية للعامل. راجع v8.getHeapSnapshot() لمزيد من التفاصيل.

إذا لم يعد مؤشر ترابط العامل قيد التشغيل، والذي قد يحدث قبل إصدار حدث 'exit'، يتم رفض Promise المُرجع على الفور بخطأ ERR_WORKER_NOT_RUNNING.

worker.performance

مضاف في: v15.1.0، v14.17.0، v12.22.0

كائن يمكن استخدامه للاستعلام عن معلومات الأداء من مثيل عامل. مشابه لـ perf_hooks.performance.

performance.eventLoopUtilization([utilization1[, utilization2]])

مضاف في: v15.1.0، v14.17.0، v12.22.0

  • utilization1 <Object> نتيجة اتصال سابق بـ eventLoopUtilization().
  • utilization2 <Object> نتيجة اتصال سابق بـ eventLoopUtilization() قبل utilization1.
  • القيمة المُرجعة: <Object>

الاتصال نفسه كـ perf_hooks eventLoopUtilization()، باستثناء أن قيم مثيل العامل تُرجع.

الفرق الوحيد هو أنه، على عكس الخيط الرئيسي، يتم إجراء التمهيد داخل عامل ضمن حلقة الأحداث. لذلك، يتوفر استخدام حلقة الأحداث فورًا بمجرد بدء تنفيذ برنامج نصي العامل.

لا يشير وقت idle الذي لا يزيد إلى أن العامل عالق في التمهيد. تُظهر الأمثلة التالية كيف أن عمر العامل بأكمله لا يجمع أي وقت idle، ولكنه لا يزال قادرًا على معالجة الرسائل.

js
const { Worker, isMainThread, parentPort } = require('node:worker_threads')

if (isMainThread) {
  const worker = new Worker(__filename)
  setInterval(() => {
    worker.postMessage('hi')
    console.log(worker.performance.eventLoopUtilization())
  }, 100).unref()
  return
}

parentPort.on('message', () => console.log('msg')).unref()
;(function r(n) {
  if (--n < 0) return
  const t = Date.now()
  while (Date.now() - t < 300);
  setImmediate(r, n)
})(10)

يتوفر استخدام حلقة أحداث العامل فقط بعد إصدار حدث 'online'، وإذا تم استدعاءه قبل ذلك، أو بعد حدث 'exit'، فإن جميع الخصائص لها قيمة 0.

worker.postMessage(value[, transferList])

مضاف في: v10.5.0

إرسال رسالة إلى عامل المعالجة الذي يتم استقباله عبر require('node:worker_threads').parentPort.on('message'). راجع port.postMessage() لمزيد من التفاصيل.

worker.ref()

مضاف في: v10.5.0

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

worker.resourceLimits

مضاف في: v13.2.0، v12.16.0

يوفر مجموعة قيود موارد محرك JS لهذا مؤشر الترابط عامل المعالجة. إذا تم تمرير خيار resourceLimits إلى مُنشئ Worker، فإن هذا يطابق قيمه.

إذا توقف عامل المعالجة، فإن قيمة الإرجاع هي كائن فارغ.

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()

[السجل]

الإصدارالتغييرات
v12.5.0هذه الوظيفة تُرجع الآن وعدًا. إن تمرير مُستدعي مُهمة قديم، وكان عديم الفائدة حتى هذا الإصدار، حيث تم إنهاء عامل الترابط بشكل متزامن بالفعل. أصبح الإنهاء الآن عملية غير متزامنة بالكامل.
v10.5.0مضاف في: v10.5.0

إيقاف جميع عمليات تنفيذ جافا سكريبت في مؤشر ترابط العامل في أقرب وقت ممكن. يُرجع وعدًا لرمز الخروج الذي يتم استيفاؤه عند إصدار حدث 'exit'.

worker.threadId

مضاف في: v10.5.0

معرّف عدد صحيح لخيط المُرجع. بداخل مؤشر ترابط العامل، يكون متاحًا كـ require('node:worker_threads').threadId. هذه القيمة فريدة لكل مثيل Worker داخل عملية واحدة.

worker.unref()

مضاف في: v10.5.0

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

ملاحظات

الحظر المتزامن لـ stdio

تستخدم وحدات Worker تمرير الرسائل عبر <MessagePort> لتنفيذ التفاعلات مع stdio. وهذا يعني أن مخرجات stdio الصادرة من وحدة Worker قد تُحظر بواسطة التعليمات البرمجية المتزامنة في الطرف المُستقبِل والتي تُحظر حلقة أحداث Node.js.

js
import { Worker, isMainThread } from 'node:worker_threads'

if (isMainThread) {
  new Worker(new URL(import.meta.url))
  for (let n = 0; n < 1e10; n++) {
    // Looping to simulate work.
  }
} else {
  // This output will be blocked by the for loop in the main thread.
  console.log('foo')
}
js
'use strict'

const { Worker, isMainThread } = require('node:worker_threads')

if (isMainThread) {
  new Worker(__filename)
  for (let n = 0; n < 1e10; n++) {
    // Looping to simulate work.
  }
} else {
  // This output will be blocked by the for loop in the main thread.
  console.log('foo')
}

تشغيل مؤشرات ترابط العامل من نصوص التحميل المسبق

توخ الحذر عند تشغيل مؤشرات ترابط العامل من نصوص التحميل المسبق (النصوص المحملة والمشغّلة باستخدام علم سطر الأوامر -r). ما لم يتم تعيين خيار execArgv بشكل صريح، فإن مؤشرات ترابط العامل الجديدة ترث تلقائيًا أعلام سطر الأوامر من العملية الجارية وستقوم بتحميل نفس نصوص التحميل المسبق مثل مؤشر الترابط الرئيسي. إذا قام نص التحميل المسبق بتشغيل مؤشر ترابط عامل بشكل غير مشروط، فسوف يقوم كل مؤشر ترابط تم إنشاؤه بإنشاء مؤشر ترابط آخر حتى تتعطل التطبيقات.