繁体   English   中英

异步遍历任务树

[英]Asynchronously traverse a task tree

对于任务树,如下所示:

var taskTree = {
  a: task_a,
  b: ()=> {
    'b1': task_b1,
    'b2': task_b2
  }),
  c: task_c,
  d: task_d
};

如何异步遍历任务树,以便先执行父节点,然后异步执行子节点? 我很期待这个:

Starting task with id: 1
Starting task with id: 2
Starting task with id: 3
Starting task with id: 4
Finishing task with id: 1
Finishing task with id: 2
Finishing task with id: 3
Finishing task with id: 4
Starting task with id: 11
Starting task with id: 22
Starting task with id: 33
...

我试图弄清楚如何像我需要的那样异步执行任务,但即使这样也没有给出预期的结果。

 async function promise(id) { console.log(`Starting task with id: ${id}`); return new Promise((resolve, reject) => { setTimeout(async () => { console.log(`Finishing task with id: ${id}`); resolve(true); if(id == 1) { await Promise.all([promise(11), promise(111), promise(1111)]); } if(id == 2) { await Promise.all([promise(22), promise(222), promise(2222)]); } if(id == 3) { await Promise.all([promise(33), promise(333), promise(3333)]); } if(id == 4) { await Promise.all([promise(44), promise(444), promise(4444)]); } }, 100); }); } async function test() { const p1 = promise(1); const p2 = promise(2); const p3 = promise(3); const p4 = promise(4); const result = await Promise.all([p1, p2, p3, p4]); } test()

基本上,

 async function exec(task) { await task.fn() await Promise.all(task.subs.map(exec)) } // let work = (s) => new Promise(r => setTimeout(() => r(console.log('done', s)))) tasks = [ { fn: () => work(1), subs: [ { fn: () => work(11), subs: [] }, { fn: () => work(12), subs: [ { fn: () => work(121), subs: [ { fn: () => work(1211), subs: [], }, { fn: () => work(1212), subs: [], } ] } ] }, ] }, { fn: () => work(2), subs: [], } ] async function test() { await Promise.all(tasks.map(exec)); } test()

这是使用object-scan的解决方案。 首先我们确定应该并行执行的任务,然后执行它们。

 // const objectScan = require('object-scan'); const tasks = (() => { const work = (s) => new Promise((resolve) => { console.log('start', s); setTimeout(() => { console.log('done', s); resolve(); }, 10); }); return [ { fn: () => work(1), subs: [ { fn: () => work(11), subs: [ { fn: () => work(111), subs: [] } ] }, { fn: () => work(12), subs: [ { fn: () => work(121), subs: [ { fn: () => work(1211), subs: [] }, { fn: () => work(1212), subs: [] } ] } ] } ] }, { fn: () => work(2), subs: [ { fn: () => work(21), subs: [] } ] } ]; })(); const extractor = objectScan(['**(^subs$).fn'], { useArraySelector: false, filterFn: ({ depth, value, context }) => { while (context.length <= depth) { context.push([]); } context[depth].push(value); } }); (async () => { const fns = extractor(tasks, []); for (let idx = 0; idx < fns.length; idx += 1) { // eslint-disable-next-line no-await-in-loop await Promise.all(fns[idx].reverse().map((fn) => fn())); } })(); // => start 1 // => start 2 // => done 1 // => done 2 // => start 11 // => start 12 // => start 21 // => done 11 // => done 12 // => done 21 // => start 111 // => start 121 // => done 111 // => done 121 // => start 1211 // => start 1212 // => done 1211 // => done 1212
 .as-console-wrapper {max-height: 100%;important: top: 0}
 <script src="https://bundle.run/object-scan@14.2.0"></script>

免责声明:我是对象扫描的作者

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM