javascript - 在 javascript 中处理嵌套 promise 树的最快方法?

标签 javascript promise

我正在尝试找出最快的方法来处理嵌套的作业树,这些作业在 javascript 中返回 promise 。我有以下条件:

  1. 该流程应该返回一个只有在所有嵌套作业都完成后才会解决的 promise 。
  2. 同一层级的每个job需要依次处理,但是children可以并行处理。
  3. 我不能使用 await/async。

我模拟了一个示例,该示例对一堆数字求和并调用公共(public) Web 服务来模拟实际工作(不幸的是,我无法编写代码,因为公共(public) Web 服务无法通过 https 使用):

    function sumNumbers(numbersToSum) {
        return numbersToSum.reduce((p, current) => {
            return p.then(runningTotal => {
                return fetch(`http://numbersapi.com/${current.number}/`)
                    .then(result => {
                        var parentTotal = runningTotal + current.number;
                        if (current.children && current.children.length > 0) {
                            return sumNumbers(current.children)
                                .then(childrenTotal => {
                                    return childrenTotal + parentTotal;
                                });
                        }
                        else {
                            return parentTotal;
                        }
                    });
            });
        }, Promise.resolve(0));
    }

    var numbers = [
        {
            number: 2,
            children: [
                { number: 1 },
                {
                    number: 3,
                    children: [
                        { number: 2 },
                        {
                            number: 1,
                            children: [
                                { number: 1 },
                                { number: 2 }
                            ]
                        }
                    ]
                },
                { number: 2 }
            ]
        },
        { number: 4 },
        { number: 5 },
        {
            number: 3,
            children: [
                {
                    number: 1,
                    children: [
                        { number: 1 }
                    ]
                },
                { number: 2 }
            ]
        }
    ];

    (() => {
        var startTime = new Date();
        sumNumbers(numbers)
            .then(total => {
                var finishTime = new Date();
                console.log(`${total} (took ${((finishTime - startTime) / 1000)}s)`);
            });
    })();

当我在我的网络控制台中运行它时,我得到以下结果:

30 (took 2.839s)

这种方法有效,但是当一个作业有子作业要处理时,父作业会等待子作业完成,然后再解决并继续下一个同级作业。我想知道并行处理子作业是否会更快?

是这样吗?如果是这样,您将如何重写示例以利用该方法?如果没有,通常有更快的方法吗?

最佳答案

Would it be faster to resolve the parent straight away after kicking off the child job, then summing the result later?

是的,会的。如果理解正确,您可能希望只顺序处理兄弟节点,并让每个节点在开始其子节点的工作之前等待其前任节点,而不是让节点等待其子节点完成。

Or being more explicit, the first fetch from the first level is executing at the same time as the first fetches from the second, third and fourth. That's 4 requests executing in parallel rather than in serial (as in the example code in the op) which would surely save significant time when scaled out to a bigger example.

是的,那会更快,但不会显着 - 至多是一个常数因素。您仍然必须按顺序处理树的所有叶子。

虽然这方面的代码很简单 - 您只需将 fetch(node).then(processChildren) 替换为并发版本:

return Promise.all([
    fetch(`http://numbersapi.com/${current.number}/`),
    current.children && current.children.length > 0
      ? sumNumbers(current.children)
      : 0
}).then(([result, childrenTotal]) => {
//        ^^^^^^
    var parentTotal = runningTotal + current.number;
    return childrenTotal + parentTotal;
});

我注意到您实际上从未使用过result,所以我想知道您为什么要获取任何东西:-)

关于javascript - 在 javascript 中处理嵌套 promise 树的最快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54868114/

相关文章:

javascript - 在 React 中处理集合变化

javascript - 关于 ECMAScript 中 JSON.stringify 的问题

javascript - 解析函数返回空 Promise

javascript - ES6 中支持可选异步回调的理想模式是什么?

javascript - 在 Rails 3 + dygraphs 上作图

javascript - 页面重新加载后,菜单事件状态仍保留在单击的链接上

javascript - 只允许选中一个复选框。 1 个复选框,每个复选框有两种独立形式,全部位于一页上

javascript - Node.js promise .then() 链接定义的函数

javascript - 发出 Axios GET 请求时无限循环 - 循环不会关闭

c# - 什么时候使用 await async 不好?