Estoy tratando de entender por qué suceden los siguientes resultados. Apuesto a que hay algo que ver con el bucle de eventos y el hecho de que todo el código de sincronización se ejecuta antes que el código asíncrono, pero no puedo aplicar ese conocimiento a este ejemplo.
// const axios = require('axios'); const array = [1, 2, 3]; const user = {}; const promises = array.map(async (item) => { console.log('start'); user['id'] = item; const responseUser = await axios.get( `https://jsonplaceholder.typicode.com/todos/${user.id}` ); console.log('middle'); const responseUser2 = await axios.get( `https://jsonplaceholder.typicode.com/todos/${user.id}` ); console.log('end result 2: ', responseUser2.data.id); console.log('end result: ', responseUser.data.id); }); Promise.all(promises); <script type="text/javascript" src="https://unpkg.com/axios@0.21.4/dist/axios.min.js"></script>Resultados:
start start start middle middle middle end result 2: 3 end result: 3 end result 2: 3 end result: 2 end result 2: 3 end result: 1Esto sucede porque .map lanzará la devolución de llamada para cada elemento de la matriz de forma síncrona . Esas devoluciones de llamada son asíncronas, por lo que cada ejecución regresará cuando haya evaluado la primera expresión de await . Por lo tanto, obtiene un montón de ejecuciones suspendidas que solo continuarán más tarde desde un trabajo en la cola de trabajos prometidos (asincrónicamente).
Tenga en cuenta que su llamada de Promise.all se ejecutará después de todas las salidas de "inicio" , pero en realidad no está haciendo nada útil, ya que no hace nada con la promesa de que devuelve.
Cada devolución de llamada .map lanzará sincrónicamente la primera solicitud HTTP con el user.id deseado (que es el elemento actual de la matriz), pero esa evaluación de URL es el último código sincrónico que se ejecuta. Para cuando se resuelvan las promesas await -ed, user.id tendrá el valor del último elemento de la matriz.
De forma asíncrona, cada una de las ejecuciones de devolución de llamada se reanudará. En ese momento user.id ya tiene el valor del último elemento de la matriz. Estas ejecuciones reanudadas lanzarán su segunda solicitud HTTP con la última id (3). Si su intención era que esas segundas solicitudes usaran la misma id que la que la precedió en el código, entonces tendría que pasar item como consulta de URL, no item.id .