我有一些廣泛使用的代碼如下:
function getRegionUsers(region) {
return new Promise((resolve) => {
setTimeout(() => {
if (region === "emea") {
return resolve(["dave", "mike", "steve"]);
}
return resolve(["kiki", "maya", "yukiko"]);
}, 1000);
});
}
function sendMail(user, region) {
console.info(`sendMail called: ${user} (${region})`);
}
async function test() {
const regions = ["emea", "apac"];
for (const region of regions) {
const users = await getRegionUsers(region); // This line is my issue
for (const user of users) {
sendMail(user, region);
}
}
}
test();
您可以忽略前 2 個函式,它們只是幫助說明問題。問題是導致 linter 錯誤(eslint: no-await-in-loop)的第三個函式,這是有道理的,因為 await 將阻止我for回圈的每次迭代的執行。
我一直看到的解決方案是使用Promise.all這很好,除了我需要跟蹤用戶和區域,以便我可以將它傳遞給sendMail函式。因此,我最終得到了這樣的結果:
async function test() {
const regions = ["emea", "apac"];
const userPromises = regions.map((r) => getRegionUsers(r));
const regionUsers = await Promise.all(userPromises);
for (const [i, region] of regions.entries()) {
for (const user of regionUsers[i]) {
sendMail(user, region);
}
}
}
test();
這看起來很混亂和不雅,因為我基本上復制了區域for回圈并且更難遵循。一旦您處理錯誤捕獲或如果您有另一級或兩級嵌套 for 回圈,它也會變得更加混亂。
有沒有人有更優雅的解決方案(除了告訴 ESLint 忽略該行),即使它只是一種更簡潔的撰寫方式?
uj5u.com熱心網友回復:
我會用異步函式映射區域。async 函式總是回傳一個 promise(不需要添加顯式return陳述句)。并且可以等待承諾Promise.all。
async function test() {
const regions = ["emea", "apac"];
const promises = regions.map(async region => {
const users = await getRegionUsers(region);
for (const user of users) {
sendMail(user, region);
}
});
await Promise.all(promises);
}
這應該可以解決報告的問題no-await-in-loop。盡管根據您的配置,其他 ESLint 規則可能會開始抱怨。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/495172.html
標籤:javascript for循环 重构 埃斯林特 嵌套循环
