Open xxleyi opened 3 years ago
看到一个有趣的面试题:https://github.com/sl1673495/blogs/issues/55
据说是蚂蚁金服的面试题,实现起来确实有坑,在参考了已有的两个解法之后,我理清了题意,找到了或许是最简易的一种解法。
题目:
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const subFlow = createFlow([() => delay(1000).then(() => log("c"))]); createFlow([ () => log("a"), () => log("b"), subFlow, [() => delay(1000).then(() => log("d")), () => log("e")], ]).run(() => { console.log("done"); }); // 需要按照 a,b,延迟1秒,c,延迟1秒,d,e, done 的顺序打印
按照上面的测试用例,实现 createFlow:
createFlow
flow
effects
分析:题目的本质问题是,扔过来一堆嵌套的 effects,实现 run 方法,将这些 effects 以异步串行的方式执行完毕。同时,run 方法会接受单个 effects 或者回调函数,flow 执行完毕之后开始执行。
那我们就要想想,JS 中甚至抛开具体语言来说,异步串行的编程方案是什么?
或许是最佳的这个解法恰好使用了 JS 中最新的编程能力:async await + 生成器
其中:生成器可以解决嵌套问题,async await 完美契合逻辑上同步,执行上异步的异步串行。
代码:
function Flow(flow) { this.flow = flow } async function _run(effects) { for (const effect of effects) { await effect() } } const genEffects = function* (flow) { for (const e of flow) { if (Array.isArray(e)) { yield* genEffects(e) } else if (e instanceof Flow) { yield* genEffects(e.flow) } else { yield e } } } Flow.prototype.run = function (done) { _run(genEffects(this.flow)).then( () => { if (typeof done === 'function') done() } ) } function createFlow(flow) { return new Flow(flow) } const log = console.log const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const subFlow = createFlow([() => delay(1000).then(() => log("c"))]); createFlow([ () => log("a"), () => log("b"), subFlow, [() => delay(1000).then(() => log("d")), () => log("e")], ]).run(() => { console.log("done"); }); // 执行上述代码片段,会按照 a,b,延迟1秒,c,延迟1秒,d,e, done 的顺序打印
看到一个有趣的面试题:https://github.com/sl1673495/blogs/issues/55
据说是蚂蚁金服的面试题,实现起来确实有坑,在参考了已有的两个解法之后,我理清了题意,找到了或许是最简易的一种解法。
题目:
按照上面的测试用例,实现
createFlow
:flow
是指一系列effects
组成的逻辑片段。flow
支持嵌套。effects
的执行只需要支持串行。分析:题目的本质问题是,扔过来一堆嵌套的 effects,实现 run 方法,将这些 effects 以异步串行的方式执行完毕。同时,run 方法会接受单个 effects 或者回调函数,flow 执行完毕之后开始执行。
那我们就要想想,JS 中甚至抛开具体语言来说,异步串行的编程方案是什么?
或许是最佳的这个解法恰好使用了 JS 中最新的编程能力:async await + 生成器
其中:生成器可以解决嵌套问题,async await 完美契合逻辑上同步,执行上异步的异步串行。
代码: