Понимание механизма запуска js — микрозадачи и макрозадачи

JavaScript
Понимание механизма запуска js — микрозадачи и макрозадачи

Мысли, вызванные вопросом интервью.

setTimeout(function() {
  console.log(4);
}, 0);

new Promise(function(reslove) {
  console.log(1);
  reslove();
}).then(function(data) {
  console.log(3);
});

console.log(2);

Выведет: 1, 2, 3, 4. Давайте подумаем, почему.

Цикл событий eventLoop в браузере делится на синхронный стек выполнения и асинхронную очередь.Сначала будет выполняться синхронная задача.После выполнения синхронной задачи асинхронная задача будет взята из асинхронной очереди и выполнена в синхронной стек выполнения.

При использовании асинхронных очередей также будет различие между микрозадачами и макрозадачами.

  • микрозадача: микрозадачи имеют высокий приоритет и могут переходить в очередь, они не определяются первыми и выполняются первыми. В том числе: затем в обещании, наблюдателе, MutationObserver, setImmediate
  • макрозадача: макрозадача с низким приоритетом, которая определяется первой и выполняется первой. В том числе: ajax, setTimeout, setInterval, привязка событий, postMessage, MessageChannel (для обмена сообщениями)

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

На этот раз давайте рассмотрим вопрос выше: Promises — это синхронные задачи, а .then of promises — это асинхронные задачи и микрозадачи. Использование setTimeout — это задача макроса, даже если задержка равна 0, это задача макроса.

Таким образом, приведенный выше порядок выполнения заключается в том, чтобы сначала добавить setTimeout в пул задач макросов асинхронной очереди, а затем выполнить обещание вconsole.log(1), затем добавьте обещание .then в пул микрозадач в асинхронной очереди, а затем выполните синхронную задачуconsole.log(2), когда все задачи синхронизации выполнены, переходим к задачам в микрозадаче и выполняемconsole.log(3), после выполнения микрозадачи берем макрозадачу и выполняем ееconsole.log(4). Итак, порядок такой: 1, 2, 3, 4.

Расширение:

Внесите некоторые изменения в этот вопрос интервью:

setTimeout(function() {
  console.log(4);
}, 0);

new Promise(function(reslove) {
  console.log(1);
  setTimeout(function() {
    reslove('done');
  }, 0);
  reslove('first');
}).then(function(data) {
  console.log(data);
});

console.log(2);

В это время он будет выводить: 1, 2, первый, 4, вывод не выполнен, некоторые люди могут подумать, что следует выводить 1, 2, первый, 4, выполнено, на этот раз вам нужно знать, при использовании reslove, обещание состояние изменяется от pedding до разрешения,Как только состояние промиса изменилось, его нельзя изменить,такreslove('done')не будет выполняться.

когда мы ставимreslove('done')изменить наconsole.log('done'), он выведет 1, 2, сначала, 4, готово.

Сделайте еще одно сложное изменение:

setTimeout(function() {
  console.log(1);
}, 0);

new Promise(function(reslove) {
  console.log(2);
  reslove('p1');
  new Promise(function(reslove) {
    console.log(3);
    setTimeout(function() {
      reslove('setTimeout2');
      console.log(4);
    }, 0);
    reslove('p2');
  }).then(function(data) {
    console.log(data);
  });
  setTimeout(function() {
    reslove('setTimeout1');
    console.log(5);
  }, 0);
}).then(function(data) {
  console.log(data);
});

console.log(6);

Выходные результаты: 2, 3, 6, p2, p1, 1, 4, 5.

Сначала выполните синхронную задачу. Все новые обещания являются синхронными задачами, поэтому сначала выведите 2, 3, 6, а затем выполните микрозадачу. Микрозадача может перейти в очередь, поэтому она не является первой определенной p1. выполняется первым, а первый - p2 Выполнить, а затем выполнить p1. Когда все микрозадачи выполнены, выполнить макрозадачу. Макрозадача по очереди выводит 1, 4 и 5. Состояние промиса не может быть изменены, поэтому setTimeout1 и setTimeout2 не будут выводиться.

Прочтите две последние главы

  1. Если вам это нравится, пожалуйста, поставьте лайк. Если вы считаете, что это полезно для окружающих, пожалуйста, переместите палец и поделитесь им. Большое спасибо за то, что нашли время, чтобы прочитать, и за ваши лайки и репосты.
  2. Надеюсь, вы обратите внимание на мою официальную учетную запись. Новые статьи будут отправлены на официальную учетную запись как можно скорее. Официальная учетная запись в основном отправляет некоторые личные эссе, заметки для чтения, а также некоторые технические горячие точки и горячие точки в реальном времени.И есть очень привлекательная лотерея за мой счет~