Make NodeJS Promise resolution to wait for all processing to finish
Clash Royale CLAN TAG#URR8PPP
Make NodeJS Promise resolution to wait for all processing to finish
I am using util.promisify to convert Gmail API calls to promises.
async function listHistory(id, nextId, auth)
logger.info("Pulling all changes after historyId: " + id);
let gmail = google.gmail('v1');
let list = util.promisify(gmail.users.history.list);
return list(
auth: auth,
userId: 'me',
startHistoryId: id
).then(function(response)
if(typeof response !== "undefined")
if(typeof response !== "undefined")
if(typeof response.data === "object")
if(typeof response.data.history === "object")
response.data.history.forEach(function(history)
if(typeof history.messages === "object")
history.messages.forEach(function(message)
getMessage(message.id, auth); // >>> This is a network call
);
);
).catch(exception =>
logger.info("Pulling changes for historyId: " + id + " returned error: " + exception);
);
Here is the code that calls above promise returning function
let promise = await googleCloudModules.listHistory(currentHistoryId, newHistoryId, oauth2Client).then(response =>
console.log("DONE!");
).catch(exception =>
console.log(exception);
);
The promise is resolved even before all the processing is finished i.e. the forEach loop network calls. Can I make it resolve only after all network calls in foreach loop are finished?
Thanks in advance.
list()
.then.catch
also note that your nested
if
have some duplication, and can also be simplified at several steps. E.g. if (response && response.data && response.data.history) let h = response.data.history; h.forEach(...);
– Mike 'Pomax' Kamermans
Aug 10 at 19:42
if
if (response && response.data && response.data.history) let h = response.data.history; h.forEach(...);
1 Answer
1
You can use Promise.all and map all the network calls in an array. Changing a little of your code as an example
async function listHistory(id, nextId, auth)
logger.info("Pulling all changes after historyId: " + id);
let gmail = google.gmail('v1');
let list = util.promisify(gmail.users.history.list);
//you can await the list.
try
const response = await list(
auth: auth,
userId: 'me',
startHistoryId: id
)
const getMessagePromiseArray = ;
if (response && response.data && Array.isArray(response.data.history))
response.data.history.forEach(function (history)
if (Array.isArray(history.messages))
history.messages.forEach(function (message)
getMessagePromiseArray.push(getMessage(message.id, auth)); // >>> This is a network call
);
);
return Promise.all(getMessagePromiseArray);
catch (exception)
logger.info("Pulling changes for historyId: " + id + " returned error: " + exception);
;
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Give async functions a (re)read-through. What should your async function return? Because right now it's not returning a normal Promise, you're already seemingly handing the
list()
promise inside the function by giving it a.then.catch
, so what do you actually need it to return?– Mike 'Pomax' Kamermans
Aug 10 at 19:41