JavaScript Promises:使用 Breadth-First 遍历递归构建 Promise 链
JavaScript Promises: Recursively Building Promise Chain With Breadth-First Traversal
原生JavascriptES5/ES6承诺
我正在尝试导入具有递归关系的数据,因为
数据库(mongodb)正在分配 ID - 必须(异步地)加载 parent
在 children 可以加载之前(也是异步的)。
例如,此任务列表中的任务 B。
任务 A - 一些过程
任务 B - 递归异步加载(bread-first遍历)
任务 C - 依赖于任务 B
注意,因为任务 C 在任务 B 完成之前无法启动我假设
需要构建一个承诺链,该链在完成之前不会退出。
假设正在构建的链看起来像这样:
(这棵树只有1个头)
promiseParent.then(Promise.all(childrenPromises.then(Promise.all(grandChildrenPromsies.then(....)))))
我想它会像 breadth-first 队列一样遍历(我最好
尽可能避免使用队列数据结构)
我发现这个很难破解。任何建议或
解决方案?
Promise 链可以动态扩展,在链中的任何点插入新链接,只需 return 任何 .then
履行处理程序的承诺。
假设每个任务都用其 children 的数组来解析。如果children可以并行处理,那么:
promiseParent
.then(children => Promise.all(children.map(child => loadChild(child))))
.then(grandchildren => Promise.all(grandchildren.map(child => loadChild(child))))
应该可以。如果children必须按顺序处理,那么:
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
知道 return 下一代来简化)。
如果children的数量必须递归发现,那么:
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));
因此,只要有更多事情要做,您始终可以通过 进行扩展(这就是您通过 return 从 .then
实现中获得新承诺而隐含地做的事情处理程序)。
原生JavascriptES5/ES6承诺
我正在尝试导入具有递归关系的数据,因为 数据库(mongodb)正在分配 ID - 必须(异步地)加载 parent 在 children 可以加载之前(也是异步的)。
例如,此任务列表中的任务 B。
任务 A - 一些过程
任务 B - 递归异步加载(bread-first遍历)
任务 C - 依赖于任务 B
注意,因为任务 C 在任务 B 完成之前无法启动我假设 需要构建一个承诺链,该链在完成之前不会退出。
假设正在构建的链看起来像这样: (这棵树只有1个头)
promiseParent.then(Promise.all(childrenPromises.then(Promise.all(grandChildrenPromsies.then(....)))))
我想它会像 breadth-first 队列一样遍历(我最好 尽可能避免使用队列数据结构)
我发现这个很难破解。任何建议或 解决方案?
Promise 链可以动态扩展,在链中的任何点插入新链接,只需 return 任何 .then
履行处理程序的承诺。
假设每个任务都用其 children 的数组来解析。如果children可以并行处理,那么:
promiseParent
.then(children => Promise.all(children.map(child => loadChild(child))))
.then(grandchildren => Promise.all(grandchildren.map(child => loadChild(child))))
应该可以。如果children必须按顺序处理,那么:
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
知道 return 下一代来简化)。
如果children的数量必须递归发现,那么:
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));
因此,只要有更多事情要做,您始终可以通过 .then
实现中获得新承诺而隐含地做的事情处理程序)。