【问题标题】:async loops in javascriptjavascript中的异步循环
【发布时间】:2021-11-19 20:54:42
【问题描述】:

我正在尝试总结从一系列异步调用中得到的结果

let sum = 0;
for(const id  of ids) {
  const res = await getRes(id);
  sum += res;
}

这是一种有效的方法吗?有更好的解决方案吗?

【问题讨论】:

  • 当然可以,除非您可以同时拨打所有电话到getRes,在这种情况下,您可以Promise.all 他们然后总结它们。
  • const sum = await Promise.all(ids.map(id =>getRes(id))).then(nums=>nums.reduce((a,b)=>a+b));

标签: javascript asynchronous


【解决方案1】:

您编写的代码似乎是正确的。

为了验证它,你可以编写一些单元测试,我不能说它有多难,因为我不知道getRes 在做什么以及你必须模拟哪些外部依赖项(如果有的话)。一般来说,您应该养成对代码进行单元测试的习惯:它带来的好处之一是为您提供了一种验证实现的方法。

您还可以考虑并行获取结果的想法,这实际上可以加快速度。同样,我不知道 getRes 在做什么,但我想它执行某种 IO(例如:数据库查询)。鉴于 Javascript 的单线程特性,当您有一堆 独立 异步操作时,您总是可以尝试并行执行它们并收集它们的结果,以便以后聚合它们。请注意独立这个词上的粗体:为了并行执行一堆操作,它们需要是独立的(如果不是,您的代码的正确性将失效)。

由于您正在执行数字求和,因此并行计算加数是安全的。

这是最简单的并行解决方案:

async function sum(ids) {
    const getResTasks = ids.map(id => getRes(id));
    const addends = await Promise.all(getResTasks);
    return addends.reduce((memo, item) => memo + item, 0);
}

注意:这是一个幼稚的实现。我不知道 ids 数组可以包含多少项。如果这个数字可能很大(数千项或更多),那么像前一个代码这样的代码可能会在用于获取和加数的外部依赖项上产生重载,因此需要采取一些预防措施来限制程度应该采取并行度。

【讨论】:

    猜你喜欢
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多