zoukankan      html  css  js  c++  java
  • 一道有趣的异步题

    从公众号里看到一道异步题目,花了点时间看了下,挺有意思的。
    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:
    flow 是指一系列 effects 组成的逻辑片段。
    
    flow 支持嵌套。
    
    effects 的执行只需要支持串行。
    
    原文解法:
    
        function createFlow(effects = []) {
            let sources = effects.slice().flat();
            function run(callback) {
                while (sources.length) {
                    const task = sources.shift();
                    const next = () => createFlow(sources).run(callback);
                    if (typeof task === "function") {
                        const res = task();
                        if (res?.then) {
                            res.then(next);
                            return;
                        }
                    } else if (task?.isFlow) {
                        task.run(next);
                        return;
                    }
                }
                callback?.();
            }
            return {
                run,
                isFlow: true,
            };
          }
          
    如果对嵌套思路有点不明白,可以换种思路
    
    function createFlow(effects = []) {
    let sources = effects.slice().flat();
    function run(callback) {
        if (!sources.length) {
            callback?.();
            return;
        }
        while (sources.length > 0) {
            const task = sources.shift();
            if (task?.isFlow) {
                let newSources = task.sources.concat(sources);
                createFlow(newSources).run(callback);
                break;
            } else if (typeof task === "function") {
                const res = task();
                if (res?.then) {
                    res.then(() => {
                        createFlow(sources).run(callback);
                    });
                    break;
                }
            }
          }
        }
        return {
          run,
          sources,
          isFlow: true,
        };
    }
    
    测试用例
    const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
    const subFlow = createFlow([() => delay(2000).then(() => console.log("c"))]);
    createFlow([
        () => console.log("a"),
        () => console.log("b"),
        subFlow,
        [
          () => delay(1000).then(() => console.log("d")),
          () => delay(1000).then(() => console.log("e")),
          () => delay(2000).then(() => console.log("f")),
        ],
    ]).run(() => {
        console.log("done");
    });
  • 相关阅读:
    Python入门系列——第17篇
    Python入门系列——第16篇
    Python入门系列——第15篇
    Python入门系列——第14篇
    Python入门系列——第13篇
    Python入门系列——第12篇
    python入门系列——第11篇
    Python入门系列——第10篇
    Python入门系列——第9篇
    Python入门系列——第8篇
  • 原文地址:https://www.cnblogs.com/hjj2ldq/p/13555324.html
Copyright © 2011-2022 走看看