El método Promise.race() devuelve una promesa que cumple o rechaza tan pronto como una de las promesas en un iterable cumple o rechaza, con el valor o la razón de esa promesa.
Tomado del sitio MDN.
Tengo 5 promesas y necesito saber una vez que se resuelvan 2 promesas, teniendo en cuenta el rendimiento.
const sleep = ms => new Promise(r => setTimeout(r, ms)) async function swimmer (name) { const start = Date.now() console.log(`${name} started the race`) await sleep(Math.random() * 5000) console.log(`${name} finished the race`) return { name, delta: Date.now() - start } } const swimmers = [ swimmer("Alice"), swimmer("Bob"), swimmer("Claire"), swimmer("David"), swimmer("Ed") ]; Promise.race(swimmers) .then(({ name }) => console.log(`*** ${name} is the winner!!! ***`)) .catch(console.error)Esto devolverá al nadador más rápido, pero me gustaría imprimir una vez que resuelva 2 promesas.
¿Cómo puedo hacerlo?
Podría escribir una implementación personalizada de Promise.race que devuelva una promesa que se resuelve con el resultado de 2 promesas que se resuelven antes que otras.
El siguiente ejemplo de código muestra una implementación:
function customPromiseRace(promiseArr, expectedCount) { return new Promise((resolve, reject) => { if (promiseArr.length < expectedCount) { throw new Error(`Not enough promises to get ${expectedCount} results`); } // array to store the results of fulfilled promises const results = []; for (const p of promiseArr) { Promise.resolve(p).then(result => { // push the promise fulfillment value to the "results" // array only if we aren't already finished if (results.length < expectedCount) { results.push(result); if (results.length === expectedCount) { resolve(results); } } }, reject); } }); } const sleep = ms => new Promise(r => setTimeout(r, ms)); async function swimmer(name) { const start = Date.now(); console.log(`${name} started the race`); await sleep(Math.random() * 5000); console.log(`${name} finished the race`); return { name, delta: Date.now() - start }; } const swimmers = [ swimmer('Alice'), swimmer('Bob'), swimmer('Claire'), swimmer('David'), swimmer('Ed'), ]; function customPromiseRace(promiseArr, expectedCount) { return new Promise((resolve, reject) => { if (promiseArr.length < expectedCount) { throw new Error(`Not enough promises to get ${expectedCount} results`); } const results = []; for (const p of promiseArr) { Promise.resolve(p).then(result => { if (results.length < expectedCount) { results.push(result); if (results.length === expectedCount) { resolve(results); } } }, reject); } }); } customPromiseRace(swimmers, 2).then(console.log).catch(console.error);Podrías usar .then(handleMyPromise) dentro de Promise.race .
Ejemplo:
let handlepromise1 = function ( response ){ console.log("Expected response: ",response); return response; } let promise1 = function () { return new Promise((r) => { setTimeout(()=>{ console.log("Promise1 says"); r("promise1") },2000) }) } let timeout = function(){ return new Promise((r) => { setTimeout(()=>{ console.log("timeout says"); r("timeout") },3000) }); }; (async function(){ let func = async function tt(){ let r = await Promise.race([ promise1().then(handlepromise1), timeout() ]) console.log("Result: ",r); } func() })()Resultado de la consola:
Promise1 says Expected response: promise1 Result: promise1 timeout says