Я хочу создать древовидную структуру, используя вложенные Promise
.
Когда обещания разрешаются в древовидной структуре, они разрешаются изнутри (потомок, потом родитель). Мне нужно, чтобы выполнение обещаний от родителя к брату и сестре могло выполняться параллельно.
Я придумал способ задержать выполнение, разрешив закрытие, которое будет задерживать действие из разрешенного обещания, и рекурсивно вызывая каждую функцию сверху вниз. Это довольно элегантное решение, однако, есть ли другое соглашение или функциональный объект, который я могу использовать для выполнения действия. Я действительно не хочу разрешать закрытие для каждого узла в дереве, поскольку это усложнит процесс обучения людей его использованию.
Я бы предпочел не использовать async / await и просто придерживаться Promise
или другого объекта Functional JS.
В этом первом примере будет показан разрешенный порядок вложенных Обещаний.
let order = 0
const promiseTree = (name, children) =>
Promise.all([
new Promise(res => res(`${name} order:${order++}`)),
children && Promise.all(children)
])
promiseTree('root', [
promiseTree('child', [
promiseTree('grandchild', [
promiseTree('great grandchild sibling 1'),
promiseTree('great grandchild sibling 2'),
])
])
])
.then(console.log)
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js?concise=true"></script>
Если вы решите закрытие, то рекурсивно вызывайте обратные вызовы, как только все обещания будут выполнены, порядок можно исправить.
let order = 0
const promiseTree = (name, children) =>
Promise.all([
// --------------------- resolve a closure with the resolved value contained
new Promise(res => res(() => `${name} order:${order++}`)),
children && Promise.all(children)
])
// flatMap over the tree, if it's a function call it and return the result
const recursivelyCall = x =>
Array.isArray(x)
? x.map(recursivelyCall)
: typeof(x) === 'function' ? x() : x
promiseTree('root', [
promiseTree('child', [
promiseTree('grandchild', [
promiseTree('great grandchild sibling 1'),
promiseTree('great grandchild sibling 2'),
])
])
])
// traverse the returned values and call the functions in declared order
.then(recursivelyCall)
.then(console.log)
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js?concise=true"></script>
Приветствия