javascript - await - ¿Es un antipatrón usar async/wait dentro de un nuevo constructor Promise()?
promise javascript (1)
Está utilizando efectivamente promesas dentro de la función ejecutor del constructor de promesas, por lo que este es el antipatrón del constructor de promesas.
Su código es un buen ejemplo del riesgo principal: no propagar todos los errores de forma segura. Lee por qué there .
Además, el uso de
async
/
await
puede hacer que las mismas trampas sean aún más sorprendentes.
Comparar:
let p = new Promise(resolve => {
""(); // TypeError
resolve();
});
(async () => {
await p;
})().catch(e => console.log("Caught: " + e)); // Catches it.
con un ingenuo (incorrecto) equivalente
async
:
let p = new Promise(async resolve => {
""(); // TypeError
resolve();
});
(async () => {
await p;
})().catch(e => console.log("Caught: " + e)); // Doesn''t catch it!
Busque en la consola web de su navegador la última.
El primero funciona porque cualquier excepción
inmediata
en una función ejecutor del constructor Promise rechaza convenientemente la promesa recién construida (pero dentro de cualquier
.then
estás solo).
El segundo no funciona porque cualquier excepción inmediata en una función
async
rechaza la
promesa implícita devuelta por la función
async
misma
.
Dado que el valor de retorno de una función ejecutor de constructor de promesa no se utiliza, ¡son malas noticias!
Tu codigo
No hay ninguna razón por la que no pueda definir
myFunction
como
async
:
async function myFunction() {
let array = await getAsyncArray();
return new Promise((resolve, reject) => {
eachLimit(array, 500, (item, callback) => {
// do other things that use native promises.
}, error => {
if (error) return reject(error);
// resolve here passing the next value.
});
});
}
Sin embargo, ¿por qué usar bibliotecas de control de concurrencia obsoletas cuando
await
?
Estoy usando la función
async.eachLimit
para controlar el número máximo de operaciones a la vez.
const { eachLimit } = require("async");
function myFunction() {
return new Promise(async (resolve, reject) => {
eachLimit((await getAsyncArray), 500, (item, callback) => {
// do other things that use native promises.
}, (error) => {
if (error) return reject(error);
// resolve here passing the next value.
});
});
}
Como puede ver, no puedo declarar la función
myFunction
como asíncrona porque no tengo acceso al valor dentro de la segunda devolución de llamada de la función
eachLimit
.