Tanto quanto eu entendo, no ES7 / ES2016, colocar múltiplos await
's em código funcionará de maneira semelhante ao encadeamento de .then()
promessas, o que significa que eles serão executados um após o outro e não em paralelo. Então, por exemplo, temos este código:
await someCall();
await anotherCall();
Entendi corretamente que anotherCall()
só será chamado quando someCall()
for concluído? Qual é a maneira mais elegante de chamá-los em paralelo?
Eu quero usá-lo no Node, então talvez haja uma solução com a biblioteca assíncrona?
EDIT: Não estou satisfeito com a solução fornecida nesta pergunta: Desaceleração devido à espera paralela de promessas em geradores assíncronos , porque ele usa geradores e estou perguntando sobre um caso de uso mais geral.
javascript
node.js
asynchronous
ecmascript-6
babeljs
Victor Marchuk
fonte
fonte
await
aguardaria a conclusão da primeira função inteiramente antes de executar o segundo.Promise
s nativos . A questão vinculada é sobre a biblioteca bluebird com geradores e rendimento. Conceitualmente semelhante, talvez, mas não em implementação.Respostas:
Você pode aguardar em
Promise.all()
:Para armazenar os resultados:
Observe que
Promise.all
falha rapidamente, o que significa que, assim que uma das promessas fornecidas a ele for rejeitada, a coisa toda será rejeitada.Se, em vez disso, você desejar aguardar todas as promessas cumpridas ou rejeitadas, poderá usá-lo
Promise.allSettled
. Observe que o Internet Explorer não oferece suporte nativamente a esse método.fonte
[result1, result2] = Promise.all([async1(), async2()]);
= await Promise.all
?TL; DR
Use
Promise.all
para chamadas de função paralelas, o comportamento da resposta não está correto quando o erro ocorre.Primeiro, execute todas as chamadas assíncronas de uma só vez e obtenha todos os
Promise
objetos. Segundo, useawait
nosPromise
objetos. Dessa forma, enquanto você espera pela primeiraPromise
solução, as outras chamadas assíncronas ainda estão em andamento. No geral, você só esperará enquanto a chamada assíncrona mais lenta. Por exemplo:Exemplo de JSbin: http://jsbin.com/xerifanima/edit?js,console
Advertência: não importa se as
await
chamadas estão na mesma linha ou em linhas diferentes, desde que a primeiraawait
chamada ocorra após todas as chamadas assíncronas. Veja o comentário de JohnnyHK.Atualização: esta resposta tem um tempo diferente no tratamento de erros, de acordo com a resposta do @ bergi , NÃO lança o erro à medida que o erro ocorre, mas depois que todas as promessas são executadas. Comparo o resultado com a dica de @ jonny:,
[result1, result2] = Promise.all([async1(), async2()])
verifique o seguinte snippet de códigofonte
[someResult, anotherResult] = [await someResult, await anotherResult]
se mudarconst
paralet
.await
instruções em série, certo? Ou seja, a execução pausa até que o primeiro sejaawait
resolvido e depois passa para o segundo.Promise.all
executa em paralelo.Promise.all
. Se cada solicitação for uma chamada de rede,await someResult
precisará ser resolvida antesawait anotherResult
mesmo de começar. Por outro lado, nasPromise.all
duasawait
chamadas podem ser iniciadas antes de qualquer uma ser resolvida.Atualizar:
A resposta original torna difícil (e em alguns casos impossível) lidar corretamente com as rejeições de promessas. A solução correta é usar
Promise.all
:Resposta original:
Apenas certifique-se de chamar as duas funções antes de aguardar uma:
fonte
await
os resolverão em valores reais.Existe outra maneira, sem Promise.all (), de fazer isso em paralelo:
Primeiro, temos 2 funções para imprimir números:
Isso é seqüencial:
Isto é paralelo:
fonte
Isso pode ser feito com Promise.allSettled () , que é semelhante,
Promise.all()
mas sem o comportamento à prova de falhas.Nota : Esta é uma característica borda do sangramento com suporte ao navegador limitado, então eu fortemente recomendo incluindo um polyfill para esta função.
fonte
Eu criei uma essência testando maneiras diferentes de resolver promessas, com resultados. Pode ser útil ver as opções que funcionam.
fonte
Embora a configuração de p1, p2 e p3 não os execute estritamente em paralelo, eles não suportam nenhuma execução e você pode capturar erros contextuais com uma captura.
fonte
No meu caso, tenho várias tarefas que quero executar em paralelo, mas preciso fazer algo diferente com o resultado dessas tarefas.
E a saída:
fonte
aguarde Promise.all ([someCall (), anotherCall ()]); como já mencionado, ele funcionará como uma cerca de encadeamento (muito comum em código paralelo como CUDA), portanto, permitirá que todas as promessas sejam executadas sem bloquear uma à outra, mas impedirá a execução de continuar até que TODAS sejam resolvidas.
outra abordagem que vale a pena compartilhar é o Node.js. assíncrono que também permitirá que você controle facilmente a quantidade de simultaneidade que normalmente é desejável se a tarefa estiver diretamente vinculada ao uso de recursos limitados como chamada de API, operações de E / S, etc.
Créditos ao autor do artigo Medium ( leia mais )
fonte
Eu voto em:
Esteja ciente do momento em que você chama funções, isso pode causar resultados inesperados:
Mas seguir sempre aciona a solicitação para criar um novo usuário
fonte
else
bloco.Eu crio uma função auxiliar waitAll, pode ser que possa torná-la mais doce. Por enquanto, ele só funciona no nodejs , não no chrome do navegador.
fonte
for
loop espera sequencialmente cada promessa e adiciona o resultado à matriz.