我想使用嵌套的Promise
创建树结构。
当promise在树结构中解析时,它将由内而外(子级然后父级)解析。我需要使从父级到子级的Promise的执行可以并行运行。
我想出了一种方法来解决延迟问题,方法是解决一个关闭操作,该操作将延迟已解决的Promise的操作,并从上至下递归调用每个函数。这是一个非常优雅的解决方案,但是,还有其他约定或功能对象可用于执行操作吗?我真的不希望解决树中每个节点的闭包问题,因为这样做会增加教导人们使用它的复杂性。
我宁愿不使用异步/等待,而只坚持使用Promise
或另一个Functional JS对象。
第一个示例将显示嵌套Promises的已解决顺序。
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>
欢呼
答案 0 :(得分:0)
第一个代码段的模式的问题在于,最内层的嵌套函数(参数)首先执行;在https://astexplorer.net/#/gist/777805a289e129cd29706b54268cfcfc/5a2def5def7d8ee91c052d9733bc7a37c63a6f67,https://github.com/tc39/ecma262/issues/1397处看到并突出显示行15
。
我宁愿不使用异步/等待,而只坚持使用
Promise
或其他功能性JS对象。
不清楚为什么不考虑该选项。 async
函数是Promise
的实例。鉴于需求async/await
是可行的解决方案。
console.log((async() => void 0)() instanceof Promise);
const fn = async() => {
let order = 0
const promiseTree = name =>
new Promise(res => res(`${name} order:${order++}`))
const res = [await promiseTree('root'), [
await promiseTree('child'), [
await promiseTree('grandchild'), [
await promiseTree('great grandchild sibling 1')
, await promiseTree('great grandchild sibling 2')
]
]
]];
return res;
}
fn()
.then(console.log)