co模块的前端实现

发布时间:2019-08-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了co模块的前端实现脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

其实就是照着网上的介绍和co的码实现了一个自己用的前端async模块。支持RequireJS和SeaJS,支持$.ajax。
有喜欢co但是不知道怎么用的前端朋友可以拿去用。

co模块的意义和原理在sf上已经有详细的介绍了,具体参见:
http://segmentfault.com/a/1190000002732081

用法:

async(function* () {
    VAR a = yield Promise.resolve(1);
    console.LOG(a);
    var b = yield [PRomise.resolve(2), Promise.resolve(3)];
    console.log(b);
    return 4;
}).then(function (value) {
    console.log(value);
}).catch(function (e) {
    // 异常处理
});

// 输出结果应该为 1 [2,3] 4

源码:

/*global exports*/
'use strict';
(function (factory) {
    // 各种模块加载方式的处理
    if (tyPEof define === 'function' && define.amd) {
        define([], factory);
    } else if (typeof define === 'function' && define.cmd) {
        define(function (require, exports, module) {
            module.exports = factory(jquery);
        });
    } else if (typeof exports === 'object') {
        exports.async = factory();
    } else {
        // window.async=factory();
    }
}(function () {
    // 下面这俩函数是有用的
    function async(generator) {
        // 主Promise
        return new Promise(function (resolve, reject) {
            var g = generator();
            /**
             *  该函数会在异步过程执行完毕后被调用,会唤醒主函数继续执行到下一个yield或return为止。
             *  参数val为异步过程的结果,即promise.result。
             *  返回值为主函数内yield或return的结果,
             *  如果是yield则必须为promise或可被autoPack包装的对象,或者包含前两者的数组
             */
            function next(val) {
            
                // 将上次运行结果返回给主函数,令主函数继续执行到下一处中断,并将结果存入result
                var result = g.next(val);
                // 暂存主函数运行结果
                var promise = result.value;
                // 判断主函数是否执行完毕,执行完毕则调用resolve完成主Promise,否则继续执行
                if (!result.done) {
                    // 判断主函数提供的参数是否为数组,
                    // 如果不是数组则用autoPack封装后通过then(next)绑定下一步流程。并通过catch(reject)抛出异常
                    // 如果是数组则对每个成员进行封装后用Promise.All打包,然后继续执行。
                    if (promise instanceof Array) {
                        Promise.all(promise.map(autoPack)).then(next).catch(reject);
                    } else {
                        autoPack(promise).then(next).catch(reject);
                    }
                } else {
                    resolve(promise);
                }
            }

            // 捕获并通过reject抛出异常
            try {
                next();
            } catch (e) {
                reject(e);
            }
        })
    }

    // 自动打包,可以将第三方实现的Promise工具打包为ES6标准的Promise
    // 目前仅支持jQuery.Promise
    function autoPack(target) {
        // 包装$.ajax
        if (target.error) {
            return new Promise(function (resolve, reject) {
                target.done(resolve).error(reject);
            })
        } else {
            return target;
        }
    }

    return async;
}));

脚本宝典总结

以上是脚本宝典为你收集整理的co模块的前端实现全部内容,希望文章能够帮你解决co模块的前端实现所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。