Por lo que yo entiendo, en ES7 / ES2016, poner múltiples await
's en el código funcionará de manera similar a encadenar .then()
con promesas, lo que significa que se ejecutarán uno tras otro en lugar de en parallerl. Entonces, por ejemplo, tenemos este código:
await someCall();
await anotherCall();
¿Entiendo correctamente que anotherCall()
se llamará solo cuando someCall()
se complete? ¿Cuál es la forma más elegante de llamarlos en paralelo?
Quiero usarlo en Node, ¿tal vez hay una solución con la biblioteca asíncrona?
EDITAR: no estoy satisfecho con la solución proporcionada en esta pregunta: ralentización debido a la espera no paralela de promesas en generadores asíncronos , porque usa generadores y estoy preguntando sobre un caso de uso más general.
javascript
node.js
asynchronous
ecmascript-6
babeljs
Victor Marchuk
fuente
fuente
await
esperaría a que se completara la primera función completamente antes de ejecutar el segundo.Promise
S. La pregunta vinculada se refiere a la biblioteca de bluebird con generadores y rendimiento. Conceptualmente similar quizás, pero no en implementación.Respuestas:
Puedes esperar en
Promise.all()
:Para almacenar los resultados:
Tenga en cuenta que
Promise.all
falla rápidamente, lo que significa que tan pronto como una de las promesas que se le suministran rechaza, todo lo rechaza.Si, en cambio, desea esperar a que se cumplan o rechacen todas las promesas, puede usarlas
Promise.allSettled
. Tenga en cuenta que Internet Explorer no admite de forma nativa este método.fuente
[result1, result2] = Promise.all([async1(), async2()]);
= await Promise.all
?TL; DR
Utilice
Promise.all
para las llamadas a funciones paralelas, los comportamientos de respuesta no son correctos cuando se produce el error.Primero, ejecute todas las llamadas asincrónicas a la vez y obtenga todos los
Promise
objetos. En segundo lugar, utilizarawait
en losPromise
objetos. De esta manera, mientras espera a que el primero sePromise
resuelva, las otras llamadas asincrónicas siguen progresando. En general, solo esperará tanto como la llamada asincrónica más lenta. Por ejemplo:Ejemplo de JSbin: http://jsbin.com/xerifanima/edit?js,console
Advertencia: no importa si las
await
llamadas están en la misma línea o en líneas diferentes, siempre y cuando la primeraawait
llamada ocurra después de todas las llamadas asincrónicas. Ver el comentario de JohnnyHK.Actualización: esta respuesta tiene un tiempo diferente en el manejo de errores de acuerdo con la respuesta de @ bergi , NO arroja el error a medida que ocurre el error, pero después de que se ejecutan todas las promesas. Comparo el resultado con el consejo de @ jonny:
[result1, result2] = Promise.all([async1(), async2()])
verifique el siguiente fragmento de códigofuente
[someResult, anotherResult] = [await someResult, await anotherResult]
si cambiasconst
alet
.await
declaraciones en serie, ¿verdad? Es decir, la ejecución se detiene hasta que seawait
resuelve el primero , luego pasa al segundo.Promise.all
Se ejecuta en paralelo.Promise.all
. Si cada solicitud es una llamada de red,await someResult
deberá resolverseawait anotherResult
incluso antes de comenzar. Por el contrario, enPromise.all
las dosawait
llamadas se puede iniciar antes de que se resuelva una.Actualizar:
La respuesta original hace que sea difícil (y en algunos casos imposible) manejar correctamente los rechazos de promesas. La solución correcta es usar
Promise.all
:Respuesta original:
Solo asegúrese de llamar a ambas funciones antes de esperar una:
fuente
await
luego los resolverán en valores reales.Hay otra forma sin Promise.all () para hacerlo en paralelo:
Primero, tenemos 2 funciones para imprimir números:
Esto es secuencial:
Esto es paralelo:
fuente
Esto se puede lograr con Promise.allSettled () , que es similar
Promise.all()
pero sin el comportamiento de falla rápida.Nota : Esta es una característica de última generación con compatibilidad limitada con el navegador, por lo que recomiendo incluir un polyfill para esta función.
fuente
He creado una esencia que prueba algunas formas diferentes de resolver promesas, con resultados. Puede ser útil ver las opciones que funcionan.
fuente
Si bien establecer p1, p2 y p3 no los ejecuta estrictamente en paralelo, no retrasan ninguna ejecución y puede atrapar errores contextuales con un catch.
fuente
En mi caso, tengo varias tareas que quiero ejecutar en paralelo, pero necesito hacer algo diferente con el resultado de esas tareas.
Y la salida:
fuente
aguarde Promise.all ([someCall (), anotherCall ()]); como ya se mencionó, actuará como una cerca de hilos (muy común en código paralelo como CUDA), por lo tanto, permitirá que todas las promesas se ejecuten sin bloquearse entre sí, pero evitará que la ejecución continúe hasta que TODOS se resuelvan.
Otro enfoque que vale la pena compartir es el asíncrono Node.js que también le permitirá controlar fácilmente la cantidad de concurrencia que generalmente es deseable si la tarea está directamente vinculada al uso de recursos limitados como llamadas API, operaciones de E / S, etc.
Créditos para el autor del artículo medio ( leer más )
fuente
Yo voto por:
Tenga en cuenta el momento en que llama a las funciones, puede causar resultados inesperados:
Pero el siguiente siempre activa la solicitud para crear un nuevo usuario
fuente
else
bloque.Creo una función auxiliar waitAll, puede ser que la haga más dulce. Solo funciona en nodejs por ahora, no en el navegador Chrome.
fuente
for
ciclo espera secuencialmente cada promesa y agrega el resultado a la matriz.