try promises node example catch await async javascript asynchronous promise async-await

javascript - promises - node js 6 async await



¿Cómo espero múltiples promesas en paralelo sin un comportamiento "fallido"? (2)

Si bien la técnica en la respuesta aceptada puede resolver su problema, es antipatrón. Resolver una promesa con un error no es una buena práctica y hay una manera más limpia de hacerlo.

Lo que quieres hacer es en pseudo idioma es:

fn task() { result-1 = doAsync(); result-n = doAsync(); // handle results together return handleResults(result-1, ..., result-n) }

Esto se puede lograr simplemente con async / Promise.all sin la necesidad de usar Promise.all . Un ejemplo de trabajo:

console.clear(); function wait(ms, data) { return new Promise( resolve => setTimeout(resolve.bind(this, data), ms) ); } /** * This will be runned in series, because * we call a function and immediately wait for it''s result, * so this will finish in 1s. */ async function series() { return { result1: await wait(500, ''seriesTask1''), result2: await wait(500, ''seriesTask2''), } } /** * While here we call the functions first, * then wait for the result later, so * this will finish in 500ms. */ async function parallel() { const task1 = wait(500, ''parallelTask1''); const task2 = wait(500, ''parallelTask2''); return { result1: await task1, result2: await task2, } } async function taskRunner(fn, label) { const startTime = performance.now(); console.log(`Task ${label} starting...`); let result = await fn(); console.log(`Task ${label} finished in ${ Number.parseInt(performance.now() - startTime) } miliseconds with,`, result); } void taskRunner(series, ''series''); void taskRunner(parallel, ''parallel'');

Nota: Necesitará un navegador que tenga habilitado async / await para ejecutar este fragmento.

De esta forma puede usar simplemente try / catch para manejar sus errores y devolver resultados parciales dentro de la función parallel .

Estoy usando async / await para disparar varias llamadas de api en paralelo:

async function foo(arr) { const results = await Promise.all(arr.map(v => { return doAsyncThing(v) })) return results }

Sé que, a diferencia de los loops , Promise.all ejecuta en paralelo (es decir, la porción de espera de resultados está en paralelo).

Pero también sé que :

Promise.all se rechaza si se rechaza uno de los elementos y Promise.all falla rápidamente: si tiene cuatro promesas que se resuelven después de un tiempo de espera, y una rechaza inmediatamente, Promise.all rechaza inmediatamente.

Mientras leo esto, si Promise.all con 5 promesas, y el primero en finalizar devuelve un reject() , entonces los otros 4 se cancelan efectivamente y se pierden los valores prometidos de resolve() .

Hay una tercera forma? Donde la ejecución es efectivamente en paralelo, pero una sola falla no arruina todo el grupo?


Usar catch significa que la promesa se resuelve (a menos que arroje una excepción de la catch o rechace manualmente la cadena de promesa), por lo que no necesita devolver explícitamente una promesa resuelta IIUC.

Esto significa que simplemente manejando los errores con la catch puede lograr lo que quiere.

Si desea estandarizar la forma en que se manejan los rechazos, puede aplicar una función de tratamiento de rechazo a todas las promesas.

async function bar() { await new Promise(r=> setTimeout(r, 1000)) .then(()=> console.log(''bar'')) .then(()=> ''bar result''); } async function bam() { await new Promise((ignore, reject)=> setTimeout(reject, 2000)) .catch(()=> { console.log(''bam errored''); throw ''bam''; }); } async function bat() { await new Promise(r=> setTimeout(r, 3000)) .then(()=> console.log(''bat'')) .then(()=> ''bat result''); } function handleRejection(p) { return p.catch(err=> ({ error: err })); } async function foo(arr) { console.log(''foo''); return await Promise.all([bar(), bam(), bat()].map(handleRejection)); } foo().then(results=> console.log(''done'', results));