原生Javascript ES5 / ES6承诺
我试图导入具有递归关系的数据 数据库(mongodb)正在分配id - 必须加载父(异步) 在它之前可以加载孩子(也是异步)。
例如,此任务列表中的任务B.
任务A - 某些过程
任务B - 递归异步加载(先行遍历)
任务C - 取决于任务B
注意,因为任务C无法启动,直到任务B完成,我假设 需要建立一个在完成之前不会退出的承诺链。
假设正在构建的链看起来像这样: (树只有1头)
promiseParent.then(Promise.all(childrenPromises.then(Promise.all(grandChildrenPromsies.then(....)))))
我想它会像广度优先队列那样遍历(我更愿意 如果可能的话,尽量避免使用队列数据结构
我发现这个很难破解。任何建议或 溶液
答案 0 :(得分:2)
可以动态扩展Promise链,只需在任何.then
履行处理程序中返回一个承诺,就可以在链中的任意位置插入新链接。
假设每个任务都使用其子数组进行解析。如果孩子可以并行处理,那么:
promiseParent
.then(children => Promise.all(children.map(child => loadChild(child))))
.then(grandchildren => Promise.all(grandchildren.map(child => loadChild(child))))
应该这样做。如果必须按顺序处理儿童,则:
let sequence = (a, f) => a.reduce((p, c) => p.then(() => f(c)), Promise.resolve());
promiseParent
.then(kids => sequence(kids, kid => loadChild(kid)).then(() => nextGen())
.then(gkds => sequence(gkds, kid => loadChild(kid)).then(() => nextGen())
会这样做(我通过假设nextGen
知道返回下一代来简化。)
如果必须递归发现孩子的数量,那么:
let loadChildrenRecursively = child => loadChild(child)
.then(nextChild => nextChild && loadChildrenRecursively(nextChild));
promiseParent
.then(firstChild => loadChildrenRecursively(firstChild)).then(() => nextGen())
.then(firstGchild => loadChildrenRecursively(firstGchild)).then(() => nextGen())
应该这样做。
要将此概括为 N级,请选择上述任何方法,并行并,然后递归:
let doGeneration = generation =>
Promise.all(generation.map(child => loadChild(child))))
.then(offsprings => offsprings && doGeneration(offsprings))
promiseParent.then(children => doGeneration(children));
因此,只要有更多要做的事情,你就可以通过resolving a promise with another promise进行扩展(这是你通过从.then
履行处理程序返回一个新的承诺而隐含的做法。)