我有這些電話來列出來自谷歌活動目錄的用戶組
let globalGroups = null;
let groupMembers = null;
await GetCustomerId(req, res).then( async () => {
// GetGroups is async function saves groups in `globalGroups` variable
await GetGroups(token).then( () => {
globalGroups.forEach( async (group) => {
// GetGroupMembers is async function saves users in `groupMembers` variable
await GetGroupMembers(group.id, token).then( () => {
groupMembers.forEach( (member) => {
// here I log the `member` and have no issues here
if (usersIds.includes(member.id)) {
let user = users.find( ({ id }) => id === member.id );
user.group_ids.push(group.id);
}
else {
member.group_ids = [];
member.group_ids.push(group.id);
users.push(member);
usersIds.push(member.id);
}
})
})
});
// the issue is here without timeout it returns an empty array because it doesn't wait for the loop to finish
console.log(users);
res.status(200).json({"users": users}).send();
}).catch(function(err) {
console.log(err)
res.status(500).json({"error": err}).send();
});
});
這將回傳一個空陣列,除非我使用超時回傳這樣的回應
setTimeout( () => {
console.log(users);
res.status(200).json({"users": users, "next_page_link": "notFound"}).send();
}, 1000);
如何讓它等到整個回圈結束才回傳回應而不使用超時?
const GetCustomerId = async (req, res, next) => {
try {
let authorization = req.headers['authorization'].split(' ');
if (authorization[0] !== 'Bearer') {
return res.status(401).send();
} else {
await axios({
url: 'https://admin.googleapis.com/admin/directory/v1/users?domain=&maxResults=1',
method: 'get',
headers: {
'Content-Type': "application/json",
'Authorization': ' Bearer ' authorization[1]
},
})
.then((response) => {
globalCustomerId = response.data.users[0].customerId
})
.catch(function(err) {
console.log(err);
});
}
} catch (err) {
console.log(err);
}
}
const GetGroups = async (token) => {
try {
await axios({
url: 'https://admin.googleapis.com/admin/directory/v1/groups?customer=' globalCustomerId,
method: 'get',
headers: {
'Content-Type': "application/json",
'Authorization': ' Bearer ' token
},
})
.then((response) => {
globalGroups = response.data.groups;
})
.catch(function (err) {
return res.status(500).json({"error": err}).send();
});
} catch (err) {
return res.status(403).json(err).send();
}
}
const GetGroupMembers = async (groupId, token) => {
await axios({
url: "https://admin.googleapis.com/admin/directory/v1/groups/" groupId "/members",
method: 'get',
headers: {
'Content-Type': "application/json",
'Authorization': ' Bearer ' token
},
})
.then((response) => {
groupMembers = null;
groupMembers = response.data.members;
})
.catch(function (err) {
return res.status(500).json({"error": err}).send();
});
}
uj5u.com熱心網友回復:
globalGroups.forEach( async (group) => {
內部的異步方法.forEach
實際上并沒有做您可能希望它做的事情。
從本質上講array.forEach(async method)
,您正在呼叫一堆異步呼叫,陣列中的每個元素呼叫 1 個。它實際上并沒有一個一個地處理每個呼叫,然后最終解決。
切換到使用帶有 await 的常規 for 回圈,它會做你想做的事。
例如。
for (const group of globalGroups) {
await GetGroupMembers(group.id, token)
groupMembers.forEach.....
}
你可以這樣做來強制你的代碼更加同步(或者使用類似的東西Promise.all
來提高效率,同時仍然是同步的)但是代碼的另一個問題是 你被困在回呼地獄中,這導致代碼可讀性降低。
我強烈建議重構您的Get*
方法,以便它們回傳您需要的值。然后你可以做一些更干凈和可預測/確定性的事情,比如:
const globalCustomerId = await GetCustomerId(req, res);
const globalGroups = await GetGroups(token); //note: Promise.all could help here
for (const group of globalGroups) {
const groupMembers = await GetGroupMembers(group.id, token)
groupMembers.forEach.....
}
console.log(users);
res.status(200).json({"users": users}).send();
您可以將其包裝在 try/catch 中以處理錯誤處理。這會導致更清晰、更簡潔和更可預測的執行順序。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/470910.html
上一篇:R:如何從私有GitHub存盤庫的特定分支下載單個檔案?
下一篇:如何在C#中定義異步操作?