我正在尝试找出最快的方法来处理嵌套的作业树,这些作业在 javascript 中返回 promise 。我有以下条件:
- 该流程应该返回一个只有在所有嵌套作业都完成后才会解决的 promise 。
- 同一层级的每个job需要依次处理,但是children可以并行处理。
- 我不能使用 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/