JS Web Worker - это макро-задача? - PullRequest
0 голосов
/ 15 марта 2020

В каких браузерах очереди обрабатываются WebWorkers? Микрозадачи, макрозадачи или выделенные?

Мы знаем, что такие вещи, как setTimeout и setInterval - это макрозадачи, а 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');

Ответы [ 2 ]

3 голосов
/ 15 марта 2020

Рабочие запускают свое собственное событие l oop в своем собственном потоке, который выполняет как макрозадачи, так и микрозадачи. (Это HTML spe c терминология [за исключением того, что они просто используют task и microtask ]; задачи - это задания сценариев, а микрозадачи - это обещания в терминах JavaScript spe c .) Задание для запуска работника изначально является (макро) задачей, как и обратный вызов события в вашем коде. На данный момент я думаю, что единственными микрозадачами у веб-работников являются обещания. На самом деле нет, Kaiido указывает, что теперь у нас также есть queueMicroTask у рабочих.

Подробности в Событие l oop в веб-работниках спец c и в разделе заданий из JavaScript спе c.

2 голосов
/ 24 марта 2020

Этот вопрос, кажется, возник из-за нескольких недоразумений.


Сначала немного косится волос в номенклатуре, но нет ничего под названием " macro-task ". Только " task " и " microtask " являются частью HTML specs , отвечающими за Циклы событий в браузере.
В этом пункте есть некоторый смысл, поскольку вам необходимо понять, что микротрубы являются обычными задачами , которые выполняются в особый момент в событии -l oop.

Как правило, после каждого выполнения задачи браузер выполняет конечную точку микрозадачи , которая будет проверять наличие ожидающих выполнения микрозадач .

Это единственная разница между микрозадачей и задачей .

Поэтому вопрос о том, выполняется ли что-то в микрозадаче или в задаче, имеет мало смысла. Чтобы заставить что-то работать в микрозадаче , все, что вам нужно, это позвонить из queueMicroTask()*, но, опять же, это ничего не изменит.


Создание Worker является асинхронным (требуется извлечение сценария ) и, таким образом, охватывает несколько задач, различных процессов и различные циклы событий (хотя они используют одну и ту же модель обработки ).

Так сказать, если он выполняется в микрозадаче ... Синхронная часть может.

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

Теперь, IMM, самый интересный вопрос в этом вопросе о событии message .

Действительно, мы уже увидел, что у нас есть только задач , однако мы не сказали, что существует несколько очередей задач и, самое главное, все очереди задач не не имеет такого же приоритета!

Существует текущее предложение о предоставлении контроля над этими приоритетами веб-разработчикам, но это все еще предложение.

Я должен признать, что в настоящее время то, что происходит, не всегда является для меня ясной наукой, но в основном источник задач опубликованных сообщений поступает из одной из очередей задач с наивысшим приоритетом, к которому у нас есть доступ до (IIR C после кадров анимации).

Конкретно это означает, что если вы запланируете две асинхронные задачи для одного и того же события l oop, событие сообщения должно победить, даже если оно было вызвано после:

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

*, который также доступен в Workers, поэтому Promises - не единственный способ запуска микротак в Worker.

...