Почему, наконец, выполняется до обещания тогда? - PullRequest
0 голосов
/ 26 ноября 2018

Когда я выполняю следующий код, блок кода A выполняется перед блоком кода B.

return new Promise((resolve, reject) => {
  try {
    resolve()
  } finally {
    // block of code A
  }
}).then(() => {
  // block of code B
})

Но я не понимаю, почему A выполняется первым.

Разрешение (или отклонение) обещания вызывает then, соответствующее ему, поэтому я ожидаю, что блок кода B будет запущен перед блоком кода A.

Из doc :

Когда происходит любая из этих опций (разрешить / отклонить), вызываются связанные обработчики, поставленные в очередь методом then обещания.

Я также прочитал это:

исполнитель вызывается до того, как конструктор Promise даже возвращает созданный объект

исполнитель = функция, переданная в качестве параметра в объект Promise.

Последняя цитата заставляет меня думать, что try catch может быть завершено до запуска обработчиков разрешения или отклонения (до того, как функция executor будет возвращена из Promise).Это объясняет, что finally срабатывает до then.

.

ОДНОВРЕМЕННОСТИ, ОДНАКО, прежде чем продолжить, я попытался вызвать внешний API с помощью fetch и await для ответа, надеясь, чтоФункция Promise будет иметь достаточно времени, чтобы вернуть функцию executor до завершения try catch:

return new Promise(async (resolve, reject) => {
  try {
    await fetch('https://swapi.co/api/people/1/')
    resolve()
  } finally {
    // block of code A
  }
}).then(() => {
  // block of code B
})

И оказалось, что A все еще выполнялся до B. Я ожидал, что обработчик разрешения будет запущен до того, какA выполняется, поскольку resolve вызывается до выполнения A.Но я ошибаюсь и не понимаю почему.

Может кто-нибудь объяснить мне, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

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

A then block queues функция, выполняемая после разрешения обещания.Функция, которую вы передали then, запускается после всего синхронного кода.

console.log(1);
Promise.resolve().then(() => console.log(3));
console.log(2); // logs 1, 2, 3

Спецификация вызывает этот EnqueueJob.Обратите внимание, что вы должны избегать явной конструкции 1011 * при создании функции, возвращающей обещание.Асинхронная функция уже автоматически возвращает обещание.

0 голосов
/ 26 ноября 2018

Блок finally {} является частью блока try catch.Таким образом, если у вас есть более одного набора блока try catch, то каждый набор может иметь свой собственный блок finally, который будет выполняться, когда будет завершен либо блок try, либо соответствующий блок catch.

...