Невозможно понять обещание тогда и поймать поведение - PullRequest
0 голосов
/ 19 ноября 2018

Фактический вывод (при просмотре в консоли Firefox) приведенного ниже кода - ошибка1 - ошибка2 - продолжить1 - продолжить3.

Promise
  .resolve()
  .then(() => Promise.reject('error1'))
  .catch(console.log)
  .then(() => console.log('continue1'))

Promise
  .resolve()
  .then(() => Promise.reject('error2'))
  .then(() => console.log('continue2'), console.log)
  .then(() => console.log('continue3'))

Согласно моему пониманию обещаний, это должно быть - error1 - continue1 - error2 - continue3.

Нужна помощь в понимании фактического результата

Ответы [ 3 ]

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

Обещания, которые разрешают / отклоняют, помещают микрозадачу в соответствующую очередьЭта задача включает вызов любых функций обратного вызова then / catch.Сообщения в этой очереди обрабатываются в последовательности.

Итак, в вашем примере последовательность:

  • Сначала Promise.resolve() выполняется.Очередь для микрозадачи теперь имеет 1 запись:

    • Очередь = [обещание № 1 выполнено]
  • Нормальный поток выполнения продолжается до второго Promise.resolve()

  • Второй Promise.resolve() выполнен.Очередь для микрозадачи теперь имеет 2 записи:

    • Очередь = [обещание №1 выполнено, обещание №2 выполнено]
  • Нормальный поток выполнения заканчивается -- стек вызовов пуст.

  • Первый элемент в очереди извлекается и обрабатывается.then обратный вызов () => Promise.reject('error1') выполнен.Это создает новое отклоненное обещание, поэтому отклонение помещается в очередь

    • Очередь = [обещание № 2 выполнено, обещание № 1 отклонено]
  • Первый элемент в очереди извлекается и обрабатывается.then обратный вызов () => Promise.reject('error2') выполнен.Это создает новое отклоненное обещание, поэтому отклонение помещается в очередь

    • Очередь = [обещание. Тогда # 1 отклонено, обещание. Затем # 2 отклонено]
  • Первый элемент в очереди извлекается и обрабатывается.Это отклонение, поэтому catch обратный вызов console.log выполняется.Это выводит «error1» и создает новое разрешенное обещание (с неопределенным значением).Очередь

    • Очередь = [обещание. Затем # 2 отклонено, обещание.вт. № 1 решено]

... и т. Д.

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

Во-первых, бессмысленно пытаться понять возможную проблему заказа между двумя совершенно независимыми цепочками обещаний.При программировании вы должны рассматривать их порядок как неопределенный (и фактически, как только у вас есть реальные асинхронные операции внутри цепочек обещаний, которые обычно содержались бы в любых реальных реализациях цепочки обещаний, порядок станет неопределенным).Если порядок важен для вас между двумя цепочками, вам нужно добавить определенный код для координации действий двух независимых цепочек обещаний.

Итак, наблюдаемый порядок в вашем фрагменте таков:

error1
error2
continue1
continue3

Поскольку у вас нет никаких асинхронных операций ни в одном из ваших обработчиков .then() или .catch(), он просто будет переключаться между двумя цепочками обещаний (что, по-видимому, и происходит при запуске вашего сниппета).Вот как он будет в основном выполняться:

  1. Первый Promise.resolve() выполняется, что добавляет в очередь событий событие для запуска его обработчиков .then().
  2. Второй Promise.resolve() выполняет, что добавляетв очередь событий - событие для запуска его обработчиков .then().
  3. Ваша последовательность JS выполнена, поэтому управление возвращается в очередь событий.Вызывается первый обработчик .then(), который затем вставляет другое событие в очередь событий для запуска обработчика .catch() и возвращает управление обратно в цикл событий.
  4. Второй обработчик .then() находится вверху событияочередь и запускается
  5. И так далее ...

Имейте в виду, что согласно спецификации обещания каждый последующий обработчик .then() или .catch() должен выполняться асинхронно (включенследующий поворот очереди событий).Цепочка обещаний не выполняется так быстро, как может одним махом.Он выполняет следующий шаг, помещает этот шаг в очередь, а затем возвращает управление в цикл обработки событий, который выталкивает следующее событие из очереди.Это заставит вращаться управление между различными цепочками обещаний, которые не ожидают завершения чего-либо еще.

Но, повторяю, вам не следует зависеть от этого уровня порядка выполнения и, в более сложных реальных условиях.В случае с другими асинхронными операциями вы не можете попытаться предсказать порядок.Следует предположить, что эти две отдельные цепочки обещаний выполняются в неопределенном порядке за пределами синхронной части (каждая Promise.resolve()).И затем, если какой-либо конкретный порядок имеет значение для вашего кода, вы должны добавить код, чтобы фактически синхронизировать и контролировать порядок выполнения, используя Promise.all() или связывая цепочки вместе в одну разветвленную цепочку или одну цепочку последовательностей или что-то подобное в зависимости от потребностейкод.

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

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

Но вот одна из возможных и вероятных последовательностей:

  • Шаг первый: оба обещания уже выполнены
  • Шаг второй: После выполнения обоих обещаний выполняется первое then. Это приводит к тому, что оба отклоняются. Я бы не зависел от порядка, в котором эти двое исполняются по отношению друг к другу.
  • Шаг третий: будучи отвергнутым, оба обещания выполняют свое второе catch/then. Я бы не зависел от порядка, в котором эти двое исполняются по отношению друг к другу.

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

Если вы хотите, чтобы continue1 происходил до error2, вы должны организовать код, ожидающий завершения первого.

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