2017-02-21 28 views
2

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

Это то, что я наблюдаю. Пример:

function wait(delayMs) { 
    return new Promise(resolve => setTimeout(resolve, delayMs)) 
} 

let prom = wait(500) 

for (let i = 0; i < 20; ++i) 
    prom.then(() => { console.log(i) }) // OK: Display 0 to 19 in the right order 

Я наблюдаю, что порядок обратного вызова соблюден, но я не нашел никакой документации по этому вопросу. Гарантирован ли заказ обратного вызова?

EDIT: Это не вопрос о том, как скреплять обещания. Здесь у меня есть только одно обещание с несколькими обратными вызовами. Обратные вызовы передаются в then в определенном порядке. Я хотел бы знать, установлен ли порядок выполнения обратного вызова.

+0

Вопрос, как представляется, касается асинхронных вызовов в цикле 'for', а не« обратного вызова »' Promise'? – guest271314

+1

Возможный дубликат [JavaScript Promise then() ordering] (http: // stackoverflow.com/questions/29111626/javascript-prom-then-ordering) –

+0

Нет, это не дубликат. Пожалуйста, попытайтесь понять предмет, прежде чем судить об этом. Я добавил уведомление. – Paleo

ответ

5

Если вы назовете «то» на одно и то же обещание несколько раз (без цепочки), функции распознавателя будут вызываться в том же порядке, в котором они были добавлены.

В спецификациях ECMAScript 2015 указано, что «реакции» находятся в очереди в порядке размещения, если обещание будет разрешено.

http://www.ecma-international.org/ecma-262/6.0/#sec-triggerpromisereactions

25.4.1.8 TriggerPromiseReactions (реакции, аргумент)

абстрактной операции TriggerPromiseReactions принимает коллекцию PromiseReactionRecords и ставит в очередь новое задание для каждой записи. Каждое такое задание обрабатывает [[Обработчик]] PromiseReactionRecord, и если [[Обработчик]] является функцией, она передает этот аргумент.

  1. Повторите для каждой реакции в реакции, в оригинальной последовательности вставки

    с. Выполните EnqueueJob («PromiseJobs», PromiseReactionJob, «реакция, аргумент»).

Это означает, что ваши функции распознаватель будут вызываться в порядке их добавления (в вашем случае, от 0 до 19).

+0

Да! Большое спасибо! Вы спасли меня! – Paleo

2

С specs:

Если значение [[PromiseState]] внутренний слот Promise, "ожидает",

  • Append fulfillReaction как последний элемент списка, который является значением внутреннего слота [[PromiseFulfillReactions]].

Так что да, позвонив по телефону несколько раз then(), вы уверены, что порядок обратного вызова будет таким же, как тот, который вы вызываетесь.

+0

Спасибо большое! Ты спас меня тоже. :) Я отчаянно пытался найти правильный ответ, и теперь у меня есть два. Я подтвердил другое, но я обожаю вас обоих. – Paleo