Estoy tratando de crear una extensión de Chrome usando la API de Gmail . Estoy usando una llamada api para obtener cierta información, y luego recorro los resultados y ejecuto otra llamada api por resultado. Una vez que finalicen esas llamadas, se ejecutará el resto del código. El problema al que me enfrento en este momento es que el resto del código se ejecuta antes de que las búsquedas devuelvan la información.
A continuación se muestra la función que no funciona. Agregué 4 banderas en el código para ilustrar mejor el problema. El comportamiento correcto debe generar el indicador 1, luego el bucle 2, luego el bucle 3, luego el 4. Sin embargo, el comportamiento real genera el indicador 1, luego el bucle 2, luego el 4, y luego recorre el indicador 3.
Una teoría que tengo es que la causa es que estoy usando recuperaciones dentro de .then(). Si este es el problema, ¿cómo lo soluciono? ¿O tiene algo que ver con que fetch sea asíncrono? Cualquier consejo o enlace útil sería muy apreciado.
¡Muchas gracias!
let senderList = new Array(); let init = { method: 'GET', async: true, headers: { Authorization: 'Bearer ' + token, 'Content-Type': 'application/json' }, 'contentType': 'json' }; fetch( 'https://gmail.googleapis.com/gmail/v1/users/me/messages?key=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234', init) .then((response) => response.json()) .then(function(data) { console.log("Flag 1") let messageResponse = data.messages; //Array of Message Objects for (let i = 0; i < messageResponse.length; i++) { console.log("Flag 2") fetch( 'https://gmail.googleapis.com/gmail/v1/users/me/messages/' + messageResponse[i].id + '?key=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234', init) .then((response) => response.json()) .then(function(message) { let headers = message.payload.headers; console.log("Flag 3") for (let i = 0; i < headers.length; i++) { if (headers[i].name == 'From'){ senderList.push(headers[i].value); } } }); } }).then(function() { console.log("Flag 4") onSuccess(senderList); }); }Use la sintaxis async/await con Promise.all que se resuelve cuando se cumplen todas las promesas:
run(); async function run() { const list = await getSenderList(); console.log(list, list.errors); } async function getSenderList() { const API_URL = 'https://gmail.googleapis.com/gmail/v1/users/me/messages/'; const API_KEY = '?key=...'; const INIT = {method: 'GET', /* ... etc. */ }; const data = await fetchJson(API_URL + API_KEY); const senderList = []; senderList.errors = {}; await Promise.all(data.messages.map(async msg => { const msgData = await fetchJson(API_URL + msg.id + API_KEY, INIT); if (msgData instanceof Error) { senderList.errors[msg.id] = msgData; return; } const headers = msgData.payload.headers; for (const h of headers) { if (h.name === 'From') { senderList.push(h.value); } } })); return senderList; } function fetchJson(url, init) { return fetch(url, init).then(r => r.json()).catch(err => err); }