Me preguntaba cuál es el problema aquí, ¿por qué la declaración de devolución no está esperando para terminar la instrucción anterior? los orders están vacíos, aunque estoy iniciando sesión en getOrders para asegurarme de que haya datos (hay datos).
await stores.forEach(async (store) => { let arr = await getOrders(store, token, tokenType); orders.push(arr); }) return orders;Para esperar todas las promesas, necesita una matriz de promesas, que puede obtener usando map . Luego, debe usar Promise.all , de modo que esperará a que se completen todas las promesas en esa matriz.
const orders = await Promise.all( stores.map(store => getOrders(store, token, tokenType)) ); return orders;*Editar: reescrito y simplificado según la sugerencia de @PatrickRoberts
Parafraseando su comentario, en el código anterior, cuando se usaba una matriz separada con un array.push , el orden de la matriz sería indeterminado. Sin embargo, usar la matriz de resultados de Promise.all siempre coincidirá con el orden de la matriz original.
Es un malentendido común que las devoluciones de llamada asincrónicas (declaradas con async y llamadas con await) pasadas a forEach o map se ejecutarán sincrónicamente o en orden. En realidad, no lo son.
Cuando verifique el polyfill de esos métodos, encontrará una línea como esta callback.call(T, kValue, k, O);. Entonces, básicamente, solo ejecuta la devolución de llamada. Si la devolución de llamada es un método asíncrono, no espera a que se realice su ejecución. En cambio, continúa ejecutando otros códigos.
Pongamos un ejemplo usando su código, digamos que esta es la devolución de llamada:
const callback = async (store) => { let arr = await getOrders(store, token, tokenType); orders.push(arr); }) Cuando se pasó a forEach :
stores.forEach(callback); básicamente, lo que hace forEach es iterar la matriz y devolver la llamada a cada elemento. mayo se parece a esto
... loop { callback.call(...) } ... No hay espera aquí. Sin embargo, cada vez, el código dentro de su callback de llamada se ejecuta sincrónicamente, ya que se declara con async y se llama con await , lo que significa que después de que se resuelve getOrders y el resultado se envía a orders .
Por lo tanto, si desea ejecutar las devoluciones de llamada sincrónicamente y en orden, puede escribir un bucle for genérico.
async function addOrders(){ for(let store of stores) { let arr = await getOrders(store, token, tokenType); orders.push(arr); } } addOrders()