Logo, o pedido é preservado .
Após a especificação à qual você se vinculou, Promise.all(iterable)
leva um iterable
(ou seja, um objeto que suporta a Iterator
interface) como parâmetro e, posteriormente, faz uma chamada PerformPromiseAll( iterator, constructor, resultCapability)
com ele, onde o último faz iterable
uso repetido IteratorStep(iterator)
.
Isso significa que, se o iterável para o qual você entra Promise.all()
for estritamente ordenado, ele ainda será solicitado assim que for passado.
A resolução é implementada através do Promise.all() Resolve
local em que cada promessa resolvida possui um [[Index]]
slot interno , que marca o índice da promessa na entrada original.
Tudo isso significa que a saída é estritamente ordenada como entrada, desde que estritamente ordenada (por exemplo, uma matriz).
Você pode ver isso em ação no violino abaixo (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
uma exceção se você passar um iterável paraPromise.all
. Além disso, não estou ciente de nenhuma implementação de promessa de usuário que atualmente ofereça suporte a iterables, embora muitos tenham debatido e decidido contra isso na época.Promise.all
não pode ser usado para executar uma série de promessas em ordem, uma após a outra. As promessas carregadas no iterador precisam ser independentes uma da outra para que isso funcione previsivelmente.Como as respostas anteriores já declararam,
Promise.all
agrega todos os valores resolvidos com uma matriz correspondente à ordem de entrada das promessas originais (consulte Agregando promessas ).No entanto, gostaria de salientar que o pedido é preservado apenas no lado do cliente!
Para o desenvolvedor, parece que as promessas foram cumpridas em ordem, mas, na realidade, as promessas são processadas em velocidades diferentes. É importante saber quando você trabalha com um back-end remoto, pois o back-end pode receber suas promessas em uma ordem diferente.
Aqui está um exemplo que demonstra o problema usando tempos limite:
Promise.all
No código mostrado acima, três promessas (A, B, C) são dadas
Promise.all
. As três promessas são executadas em velocidades diferentes (C sendo a mais rápida e B sendo a mais lenta). É por isso que asconsole.log
declarações das promessas aparecem nesta ordem:Se as Promessas forem chamadas AJAX, um back-end remoto receberá esses valores nesta ordem. Mas no lado do cliente
Promise.all
garante que os resultados sejam ordenados de acordo com as posições originais damyPromises
matriz. É por isso que o resultado final é:Se você deseja garantir também a execução real de suas promessas, precisará de um conceito como uma fila de promessas. Aqui está um exemplo usando a fila p (tenha cuidado, você precisa agrupar todas as promessas em funções):
Fila de Promessa Sequencial
Resultado
fonte
Sim, os valores em
results
estão na mesma ordem que opromises
.Pode-se citar a especificação
Promise.all
do ES6 , embora seja um pouco complicada devido à API do iterador usada e ao construtor de promessa genérico. No entanto, você notará que cada retorno de chamada do resolvedor possui um[[index]]
atributo que é criado na iteração da matriz de promessas e usado para definir os valores na matriz de resultados.fonte