支持Promise的Generator Runner

为了更斜体文字好的理解生成器+Promise协同运作模式,自己自定义一个独立工具run(..),它会自动异步运行传递给它的生成器,直到结束

----------
Examples:
    // 把基于回调的代码转换为基于Promise的代码:
    if(!Promise.wrap) {
        Promise.wrap = function(fn) {
            return function() {
                var args = [].slice.call(arguments);
                return new Promise((resolve, reject) => {
                    fn.apply(null, args.concat(function(err, data) {
                        if(err) {
                            reject(err);
                        }else {
                            resolve(data);
                        }
                    }));
                });
            };
        };
    }

    function calc(x, y, cb) {
        var sum = x + y;
        if(sum < 10) {
            cb(null, sum);
        }else {
            cb(new Error("stack overflow"));
        }
    }

    // Generator Runner
    function run(gen) {
        var args = [].slice.call(arguments, 1);
        var it = gen.apply(this, args);
        return Promise.resolve().then(function handleNext(val) {
            var next = it.next(val);

            return (function handleResult(next) {
                if(next.done) {
                    return next.value;
                }else {
                    return Promise.resolve(next.value).then(handleNext, function handleError(err) {
                        return Promise.resolve(it.throw(err)).then(handleResult);
                    });
                }
            })(next);
        });
    }

    function* gen() {
        try {
            var res1 = yield Promise.wrap(calc)(1, 2);
            console.log("res1: ", res1);

            var res2 = yield Promise.wrap(calc)(5, 6);
            console.log("res2: ", res2);
        } catch(e) {
            console.error(e);
        }

        // 测试抛出异常后是否继续执行
        var res3 = yield Promise.wrap(calc)(3, 4);
        console.log("res3: ", res3);

        return "the end";
    }

    run(gen).then(val => console.log(val), err => console.error(err));
console output:
res1:  3
Error: stack overflow(…)
res3:  7
the end
原文链接:segmentfault.com

上一篇:CSS3动画卡顿性能优化解决方案
下一篇:OSS Web直传 (文件图片)

相关推荐

  • 🔥 Promise|async|Generator 实现&amp;原理大解析 | 9k字

    笔者刚接触async/await时,就被其暂停执行的特性吸引了,心想在没有原生API支持的情况下,await居然能挂起当前方法,实现暂停执行,我感到十分好奇。好奇心驱使我一层一层剥开有关JS异步编程的...

    3 个月前
  • 面试题1:Promise递归实现拉取数据

    题目:请用promise递归实现拉取100条数据,每次拉取20条,结束条件为当次拉取不足20条或者已经拉取100条数据 ...

    2 个月前
  • 面试官要求我们手动实现 Promise.all

    情景: 最近面试,有两次被问到手动实现 Promise.all,不幸的是我都没把这题做好。因为我没有去准备这个,我不知道手动实现已有的 API 有什么意义。 但是为了防止以后还会遇到此类题,还是记录下...

    1 个月前
  • 面试官你来,130行带你手写完整Promise

    大家好,我是雷锋蜀黍。一直在某些面试宝典看到面试官要你手撸一个promise,今天天气这么好,不如我们来搞一搞。(PS:从未看过别人的实现,本文更像是记录一个思考的过程) 最终的代码完全符合Promi...

    3 个月前
  • 阅读Promise A+规范

    本文主要是PromiseA规范(https://promisesaplus.com/)的翻译加上个人的理解。 1 什么是Promise A promise represents the eve...

    2 年前
  • 阅读 is-generator-function 源码

    (https://img.javascriptcn.com/152091d995a0b72de8b8d6aa8c0c768f) 从正则表达式 (https://img.javascriptc...

    1 年前
  • 通过koa2和Promise.race()构造一个超时取消的ajax。

    MDN上说: 你可以使用AbortController.AbortController()构造函数创建一个新的AbortController对象。 使用AbortSignal 对象完成与DOM请求...

    1 年前
  • 通过Iterator控制Promise.all的并发数

    背景 异步是 js 一个非常重要的特性,但很多时候,我们不仅仅想让一系列任务并行执行,还想要控制同时执行的并发数,尤其是在针对操作有限资源的异步任务,比如文件句柄,网络端口等等。 看一个例子。

    8 个月前
  • 通天6 regeneratorruntime未定义

    loganfsmythBrunoLM(https://stackoverflow.com/users/785065/loganfsmyth)提出了一个问题:Babel 6 regeneratorRun...

    2 年前
  • 这样理解 promise

    官网解释 promise 表示一个异步操作的最终结果。 翻译 ==可以将promise理解为一个状态机==,它存在三种不同的状态,并在某一时刻只能有一种状态 pending 表示还在执行 ...

    1 年前

官方社区

扫码加入 JavaScript 社区