В скором времени порядок сохраняется .
Следуя спецификации, с которой вы связались, Promise.all(iterable)
принимает iterable
(то есть объект, который поддерживает Iterator
интерфейс) в качестве параметра, а затем вызывает PerformPromiseAll( iterator, constructor, resultCapability)
его, где последний перебирает iterable
использование IteratorStep(iterator)
.
Это означает, что если строго повторяемый итеративный элемент, который вы передаете Promise.all()
, будет упорядочен после передачи.
Разрешающая способность реализуется через то, Promise.all() Resolve
где каждое разрешенное обещание имеет внутренний [[Index]]
слот, который отмечает индекс обещания в исходном вводе.
Все это означает, что выходные данные строго упорядочены как входные данные, если входные данные строго упорядочены (например, массив).
Вы можете увидеть это в действии в приведенной ниже скрипке (ES6):
// Used to display results
const write = msg => {
document.body.appendChild(document.createElement('div')).innerHTML = msg;
};
// Different speed async operations
const slow = new Promise(resolve => {
setTimeout(resolve, 200, 'slow');
});
const instant = 'instant';
const quick = new Promise(resolve => {
setTimeout(resolve, 50, 'quick');
});
// The order is preserved regardless of what resolved first
Promise.all([slow, instant, quick]).then(responses => {
responses.map(response => write(response));
});
throw
исключением, если вы передадите итерируемое значениеPromise.all
. Кроме того, я не знаю какой-либо реализации обещания пользовательского пространства, которая в настоящее время поддерживает передачу итераций, хотя многие обсуждали это и в то время решали против этого.Promise.all
нельзя использовать для запуска массива обещаний по порядку, одно за другим. Обещания, загруженные в итератор, должны быть независимы друг от друга, чтобы это работало предсказуемо.Как уже говорилось в предыдущих ответах,
Promise.all
агрегирует все разрешенные значения в массив, соответствующий порядку ввода исходных обещаний (см. Агрегирование обещаний ).Однако я хотел бы отметить, что заказ сохраняется только на стороне клиента!
Разработчику кажется, что Обещания были выполнены по порядку, но в действительности Обещания обрабатываются с разной скоростью. Это важно знать, когда вы работаете с удаленным бэкэндом, потому что бэкэнд может получать ваши обещания в другом порядке.
Вот пример, который демонстрирует проблему с использованием тайм-аутов:
Promise.all
В коде, показанном выше, три Обещания (A, B, C) даны
Promise.all
. Три Обещания выполняются на разных скоростях (C - самый быстрый, а B - самый медленный). Вот почемуconsole.log
заявления Обещаний отображаются в следующем порядке:Если Обещания являются вызовами AJAX, то удаленный сервер получит эти значения в этом порядке. Но на стороне клиента
Promise.all
гарантирует, что результаты упорядочены в соответствии с исходными позициямиmyPromises
массива. Вот почему окончательный результат:Если вы хотите также гарантировать фактическое выполнение ваших обещаний, вам понадобится такая концепция, как очередь обещаний. Вот пример использования p-очереди (будьте осторожны, вам нужно обернуть все обещания в функции):
Очередь обещаний
результат
источник
Да, значения в
results
том же порядке, что иpromises
.Можно сослаться на спецификацию ES6
Promise.all
, хотя она немного запутанная из-за используемого итератора api и универсального конструктора обещаний. Однако вы заметите, что у каждого обратного вызова распознавателя есть[[index]]
атрибут, который создается в итерации массива обещаний и используется для установки значений в массиве результатов.источник