JS Web Worker 是一个宏任务?

JS Web Worker is a macro task?

浏览器在哪些队列中处理 WebWorker?微任务、宏任务还是专用任务?

我们知道setTimeoutsetInterval等是宏任务,Promises是微任务。但是我找不到有关 WebWorkers 和 message 事件的任何信息。

var worker = new Worker('doWork.js');

worker.addEventListener('message', function(e) {
  console.log('Worker said: ', e.data);
}, false);

worker.postMessage('Hello World');

Worker 运行 在他们自己的线程中有自己的事件循环,运行既有宏任务也有微任务。 (那是 HTML 规范术语 [除了他们只使用 taskmicrotask];任务是脚本作业,而 microtasks 是承诺作业 JavaScript spec terms.) 运行 工作人员的工作最初是一个(宏)任务,代码中的事件回调也是如此。 目前我认为网络工作者中唯一的微任务是承诺反应。实际上没有,Kaiido points out we now have queueMicroTask在工作者中也是如此。

JavaScript 规范的 The event loop in the web workers spec, and the jobs section 中的详细信息。

这个问题好像是几个误区引起的


首先在命名法上有点乱七八糟,但没有什么叫做“macro-task”。仅 "task" and "microtask" are part of the HTML specs,负责浏览器中的事件循环。
这一点有一定意义,因为您需要了解 microtasks 只是在 event-loop 的特殊时刻执行的正常 tasks .

基本上,在每个 task execution, the browser will perform a microtask endpoint 之后将检查是否有未决的 微任务 被执行。

这是微任务任务之间的唯一区别。

所以询问 运行 是否在 微任务 或任务中是没有意义的。要在 微任务 中创建某些东西 运行,您只需从 queueMicroTask()* 调用它,但再一次,这不会改变任何东西。


creation of a Worker is asynchronous (it needs to fetch the script) and thus does span on multiple tasks, on different processes, and on different event loops (though they use the same processing model)。

这么说如果它运行在微任务中...同步部分可以。

queueMicrotask( () => {
  // Worker instance is created from a micro-task...
  const worker = new Worker('data:application/javascript,const foo="bar";');
} );


现在,IMM 这个问题最有趣的一点是关于消息事件

确实,我们已经看到我们只有 任务 ,但是我们没有说的是有几个 task queues,最重要的是,所有任务队列的优先级不同!

有一个 ongoing proposal 可以让网络开发人员控制这些优先级,但这仍然是一个提案。

我必须承认,目前发生的事情对我来说并不总是清楚的科学,但基本上 posted message task source 来自 任务队列之一 最高我们可以访问的优先级(动画帧之后的 IIRC)。

具体来说,这确实意味着如果您从同一个事件循环中安排两个异步任务,消息事件 应该获胜,即使它是在以下时间之后调用的:

setTimeout( () => console.log( 'timeout' ), 0 );
onmessage = e => console.log( 'message' );
postMessage( '', '*' );

*这在 Workers 中也可用,因此 Promises 并不是在 Worker 中 运行 微任务的唯一方法。