javascript - 从父级到子级连续执行 Promise 树
问题描述
我想使用嵌套Promise
的创建树结构。
当 promise 在树结构中解析时,它将从内到外解析(子项然后父项)。我需要让从父到子的兄弟承诺的执行可以并行运行。
我想出了一种方法来延迟执行,方法是解决一个闭包,该闭包将延迟已解决的承诺的动作,并从上到下递归调用每个函数。这是一个相当优雅的解决方案,但是,我可以使用任何其他约定或功能对象来执行该操作。我真的不想解决树中每个节点的闭包问题,因为它会增加教人们使用它的复杂性。
我宁愿不使用 async/await 而是坚持使用Promise
's 或另一个 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>
干杯
解决方案
第一个片段代码中的模式问题是最内层的嵌套函数(参数)首先执行;请参阅并突出显示https://astexplorer.net/#/gist/777805a289e129cd29706b54268cfcfc/5a2def5def7d8ee91c052d9733bc7a37c63a6f67和https://github.com/tc39/ecma262/issues/139715
处的行。
我宁愿不使用 async/await 而是坚持使用
Promise
's 或另一个 Functional 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)
推荐阅读
- r - 使用填充 ggplot2 时如何指定颜色以及如何将 pvalue 打印到绘图上
- react-native - ReactNative - 如何立即更新视图
- python - 如何计算每列中唯一的重复值
- react-native - 无法从反应原生的深层组件调用嵌套导航屏幕
- discord - 如何跨模块使用@discordjs/voice AudioPlayer 方法?
- sql - 如何在 PostgreSQL 中为绑定传递参数 - COPY (...) TO STDOUT (FORMAT binary)?
- axios - 我应该使用哪个 Axios 版本
- dart - FlutterIcon 错误:无效参数:- data.config 是必需的(未定义)
- reactjs - 视频无法在移动设备上播放 - 反应应用程序
- cpu-architecture - 1 个地址线如何为您提供 2 个字节的数据?