Как очередь заданий работает с обещанием? - PullRequest
2 голосов
/ 21 января 2020

Я изучал обещания в JS и мне стало любопытно, как обещания работают с очередями заданий за кулисами. Чтобы объяснить мою путаницу, я хочу показать вам этот код:

new Promise(function(resolve, reject) {

  setTimeout(() => resolve(1), 1000);

}).then(function(result) {

  alert(result); // 1

  return new Promise((resolve, reject) => { // (*)
    setTimeout(() => resolve(result * 2), 1000);
  });

})

Если вы посмотрите на приведенный выше код, верно ли, что обратный вызов then () заранее помещен в очередь Job и ожидает обещания разрешить? Или это правда, что обратный вызов then () помещается в очередь заданий только после разрешения обещания?

Ответы [ 2 ]

2 голосов
/ 21 января 2020

Когда приходит время вызвать обратный вызов, задание вообще не go в стандартной очереди заданий (ScriptJobs); это идет в очередь PromiseJobs. Очередь PromiseJobs обрабатывается до тех пор, пока она не станет пустой, когда заканчивается каждое задание из очереди ScriptJobs. (Подробнее в статье c: Задания и очереди заданий .)

Я не уверен, какой вывод вы ожидали от своего кода, поскольку вы этого не делали ' Скажем так, но давайте рассмотрим более простой пример:

console.log("top");
new Promise(resolve => {
    setTimeout(() => {
        console.log("timer callback");
    }, 0);
    resolve();
})
.then(() => {
    console.log("then callback 1");
})
.then(() => {
    console.log("then callback 2");
});
console.log("bottom");

Вывод этого надежно:

top
bottom
then callback 1
then callback 2
timer callback

, поскольку:

  1. Задание ScriptJobs для запуска этого выполняется сценарий
  2. console.log("top") выполняется
  3. запускается код функции исполнителя обещаний, который
    • планирует задание таймера для «прямо сейчас», которое будет go в ScriptJobs очередь сразу или почти сразу
    • Разрешает обещание (что означает, что обещание разрешено до того, как then вызвано к нему)
  4. Первые then перехватчики до первого обработчика выполнения, поставив в очередь задание PromiseJobs, потому что обещание уже выполнено
  5. Второй then подключает второй обработчик выполнения (не ставит в очередь задание, ожидает обещание от первого then)
  6. console.log("bottom") выполняется
  7. Текущее задание ScriptJob заканчивается
  8. Движок обрабатывает ожидающее задание PromiseJobs (первый обработчик выполнения)
  9. То выводит "then callback 1" и выполняет первый then 'sp romise (путем возврата)
  10. Это ставит в очередь очередное задание в очереди PromiseJobs для обратного вызова во второй обработчик выполнения
  11. Поскольку очередь PromiseJobs не пуста, следующий PromiseJob подбирается и запускается
  12. Второй обработчик выполнения выводит "then callback 2"
  13. PromsieJobs пуст, поэтому механизм подхватывает следующий ScriptJob
  14. Этот ScriptJob обрабатывает обратный вызов таймера и выводит "timer callback"

В HTML spe c они используют несколько иную терминологию: «задача» (или «макрозадача») для заданий ScriptJobs и «микрозадача» для заданий PromiseJobs (и других аналогичных заданий).

Ключевым моментом является то, что: все PromiseJobs, поставленные в очередь во время ScriptJob, обрабатываются по завершении этого ScriptJob, включая любые PromiseJobs они очередь; только когда PromiseJobs пуст, следующий запуск ScriptJob выполняется.

1 голос
/ 21 января 2020

Я бы сказал, что обратный вызов then() помещается в очередь заданий только после разрешения обещания .

Если вы изменили первый тайм-аут на 3000, вы запускаете код и он ждет до 3-х, чтобы предупредить 1. Это потому, что вам придется ждать обещания, которое будет выполнено в течение 3 секунд.

Вы получите ответ отсюда: { ссылка }

Обратный вызов PromiseA.then () - это задача

  • Обещание "Обещание А": задача будет помещена в очередь для микрозадач в следующем раунде события l oop (может быть в следующем раунде)

Так что и здесь микрозадача та же как «работа», как вы упомянули выше, только обещание разрешено или отклонено, обратный вызов будет помещен в очередь задание / микрозадача.

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