使 NodeJS 承诺解析以等待所有处理完成



我正在使用util.promisify将Gmail API调用转换为承诺。

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);
});
}

这是调用上面承诺返回函数的代码

let promise = await googleCloudModules.listHistory(currentHistoryId, newHistoryId, oauth2Client).then(response => {
console.log("DONE!");
}).catch(exception => {
console.log(exception);
});

即使在所有处理完成之前,即forEach循环网络调用,承诺也会得到解决。我是否可以仅在 foreach 循环中的所有网络调用完成后才使其解析?

提前谢谢。

您可以使用Promise.all 并将所有网络调用映射到数组中。以更改一些代码为例

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);
};
}

最新更新