Quiero ejecutar un ciclo con promesas, pero quiero ejecutar un método solo después de que se complete el ciclo.
Este es un ejemplo similar de lo que quiero hacer.
const array = ['a', 'b', 'c']; console.log('start'); array.forEach((i) => { setTimeout(()=> console.log(i), 3000); }); console.log('end');este es el resultado que obtuve.
start end a b cEs fácilmente factible con algo como Promise.all una vez que sepa cómo hacerlo.
La clave es crear una matriz de Promises y luego llamar a Promise.all en él.
Pero antes de que pueda mostrar, necesitamos hacer algunos ajustes:
Primero ajustemos setTimeout para devolver una promesa:
function delay(amount) { return new Promise((resolve) => { setTimeout(resolve, amount); }); }Luego cambie el código para enviar todas las promesas creadas a una matriz:
const array = ['a', 'b', 'c']; let promises = []; async function doSomething(i) { console.log(i); await delay(3000); } console.log('start'); array.forEach((i) => { const promise = doSomething(i); promises.push(promise); }); Aquí doSomething está haciendo el trabajo asíncrono.
Por último, esperamos que todas las Promesas se resuelvan con Promise.all :
await Promise.all(promises); console.log('end');Da:
start a b c end function delay(amount) { return new Promise((resolve) => { setTimeout(resolve, amount); }); } const array = ['a', 'b', 'c']; let promises = []; async function doSomething(i) { console.log(i); await delay(3000); } console.log('start'); array.forEach((i) => { const promise = doSomething(i); promises.push(promise); }); Promise.all(promises).then(() => { console.log('end'); });Una opción es hacer lo siguiente:
const array = ['a', 'b', 'c']; console.log('start'); const promises = []; array.forEach((i) => { promises.push(new Promise(resolve => setTimeout(() => { console.log(i) resolve() }, 3000))) }) Promise.all(promises).then(() => { console.log('end'); })setTimeout es asíncrono, pero no se puede ejecutar como una promesa. Si su pregunta directa es ejecutar su código cuando finalicen todos los tiempos de espera, debe hacerlo de la siguiente manera:
const array = ['a', 'b', 'c']; let numberOfTimeoutsToBeExecuted = array.length; // keep track of the number of timeouts that have finished execution let numberOfTimeoutsExecuted = 0; console.log('start'); array.forEach((i) => { setTimeout(() => { console.log(i), numberOfTimeoutsExecuted += 1; // execute your code when the last timeout has finished execution if (numberOfTimeoutsToBeExecuted === numberOfTimeoutsExecuted) { console.log('end'); } }, 3000); });Sin embargo, si desea esperar a que varias promesas terminen de ejecutarse, la siguiente es la mejor manera de hacerlo:
const array = ['a', 'b', 'c']; const promises = []; console.log('start'); array.forEach((i) => { // add all promises that will be executed into array promises.push(new Promise((resolve, reject) => { setTimeout(()=> { console.log(i); resolve(); }, 3000); })); }); // execute all promises here Promise.all(promises).then(() => console.log('end'));