Я пытаюсь найти самый быстрый способ обработки вложенного дерева заданий, которые возвращают обещания в javascript.У меня есть следующие условия:
- Процесс должен возвращать обещание, которое разрешается только после завершения всех вложенных заданий.
- Каждое задание на одном уровне необходимо обрабатывать впоследовательность, но потомки могут обрабатываться параллельно.
- Я не могу использовать await / async.
Я смоделировал пример, который суммирует группу чисел и вызывает общедоступныйвеб-сервис для имитации выполнения реальной работы (к сожалению, я не могу зашифровать это, поскольку общедоступный веб-сервис недоступен через 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)
Этот подход работает, но когда в задании есть дочерние элементы для обработки, родительский процесс ожидает завершения дочерних заданий, прежде чем разрешить и перейти к следующему братскому заданию.Мне интересно, будет ли быстрее обрабатывать дочерние задания параллельно?
Это так?Если да, то как бы вы переписали пример, чтобы воспользоваться этим подходом?Если нет, есть ли более быстрый способ сделать это в целом?