繁体   English   中英

优雅的解决方案 - 嵌套 for 循环(eslint no-await-in-loop)

[英]Elegant solution - Nested for loops (eslint no-await-in-loop)

我有一些广泛工作的代码如下:

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

您可以忽略前两个功能,它们只是帮助说明问题。 问题是第三个 function 会导致 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 忽略该行),即使它只是一种更简洁的编写方式?

我会 map 具有异步 function 的区域。异步 function 始终返回 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 规则可能会开始报错。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM