Estoy atrapado en una situación en mecanografiado.
Tengo un bucle forEach en el que se ejecuta un método de llamada API methodOne() ; dentro de este método, se ejecuta [secuencialmente] otra llamada API a methodTwo() .
Ahora mi requisito es que el ciclo forEach debe esperar hasta que se ejecuten ambas llamadas API y luego, después de esto, forEach debe ir a su próxima iteración.
El flujo de código se ve así:
list.forEach(item => { methodOne(item); }) methodOne(){ methodTwo(); } methodTwo(){ //some code.. } Nota : no estoy usando async, await, Promise or Observables en la llamada API
Tenga en cuenta que las funciones asíncronas (tanto .then() como async/await await ) no funcionarán dentro forEach TAMBIÉN . El enfoque .then() no funcionará ni en forEach ni for bucles for.
Para ejecutar una función asíncrona dentro de un ciclo, debe usar el enfoque async/await dentro de un ciclo for o una función de recurrencia.
En el siguiente ejemplo, usaremos el enfoque async/await dentro de un bucle for .
const list = ['firstItem', 'secondeItem', 'lastItem']; // First method // use `i` parameter to check in which index the method was called function methodOne(i: string): Promise<void> { return new Promise((resolve) => { setTimeout(() => { console.log(`Make the first API call at index ${i}`); resolve(); }, 1000); }); } // Second method // use `i` parameter to check in which index the method was called function methodTwo(i: string): Promise<void> { return new Promise((resolve) => { setTimeout(() => { console.log(`Make the second API call at index ${i}`); resolve(); }, 1000); }); } // run both methods sequentially inside a `for` loop async function runMethodOneAndMethodTwoInsideLoop (): Promise<void> { for (let i in list) { await methodOne(i); await methodTwo(i); } } runMethodOneAndMethodTwoInsideLoop(); Para llamar a methodTwo dentro methodOne (que no recomiendo) puede usar el siguiente ejemplo.
const list = ['firstItem', 'secondeItem', 'lastItem']; // First method // use `i` parameter to check in which index the method was called function methodOne(i: string): Promise<void> { return new Promise((resolve) => { setTimeout(async () => { console.log(`Make the first API call at index ${i}`); await methodTwo(i); resolve(); }, 1000); }); } // Second method // use `i` parameter to check in which index the method was called function methodTwo(i: string): Promise<void> { return new Promise((resolve) => { setTimeout(() => { console.log(`Make the second API call at index ${i}`); resolve(); }, 1000); }); } // run only `methodOne` inside a `for` loop since `methodTwo` will be called inside `methodOne` async function runMethodOneInsideLoop(): Promise<void> { for (let i in list) { await methodOne(i); } } runMethodOneInsideLoop();Para obtener más información sobre las funciones asíncronas y cómo usarlas dentro de los bucles, consulte esta esencia que creé.
¡A! ¡Como eso! ¿Éste?
Simplemente alimente un montón de devoluciones de llamada asíncronas a promiseChain , y las ejecutará secuencialmente.
function methodTwo() { // some code.. return Promise.resolve(); // <= Or any async code } function methodOne(item: number) { return methodTwo().then(result => { // some code.. return { item, result }; }); } async function promiseChain<T>(callbacks: (() => Promise<T>)[]) { var output: T[] = []; for (const callback of callbacks) { const result = await callback(); output.push(result); } return output; } const list = [1, 2, 3, 4]; promiseChain(list.map(item => () => methodOne(item))) .then(responses => { // DO STUFF HERE const first_response = responses[0]; // Result of `methodOne(list[0])` const second_response = responses[1]; // Result of `methodOne(list[1])` });