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;
}));
    原文作者:WoodenSail
    原文地址: https://segmentfault.com/a/1190000003975715
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞