理解Co庫的源碼

Co流程流程控制器源碼與理解,index.js包含理解和註釋git

簡單版本的Co庫

這個版本是重點是理解generator工做原理github

// @flow
/**
 * Created by Freax on 16-12-12.
 * @Blog http://www.myfreax.com/
 */
function co(generator) {
    let gen = generator();
    next(gen.next()); //遞歸遍歷generator.next
    function next(result) {
        if (result.done)return null;//若是generator執行完畢,直接解決退出遍歷
        let res = gen.next(result.value);
        next(res);
    }
}

co(function *gen() {
    let a = yield 1;
    console.info(a, 'a');
    let b = yield 2;
    console.info(b, 'b');
    let c = yield 3;
    console.info(c, 'c');
});

generator+promise Co庫的簡版

理解generator+promise如何工做promise

// @flow
/**
 * Created by Freax on 16-12-12.
 * @Blog http://www.myfreax.com/
 */

function isPromise(obj) {
    return typeof obj === 'object' && 'function' == typeof obj.then;
}

function co(generator) {
    return new Promise((resolve,reject)=>{
        let gen = generator();
        next(gen.next());
        function next(result) {
            if (result.done)return resolve(result.value);//若是generator執行完畢,直接解決退出遍歷
            //判斷是不是Promise,若是是promise則執行promise再進入next遞歸遍歷generator.next
            if (isPromise(result.value))return result.value.then(res => {
                let result;
                try {
                    result = gen.next(res); //拋出generator的錯誤
                }catch (e){
                    return reject(e);// 捕獲後由交給promise處理返回外部處理
                }
                next(result)
            }, err => {
                let result;
                try {
                    result = gen.throw(err); //yield返回promise進入reject後的錯誤,拋出generator的錯誤
                }catch (e){
                    return reject(e); // 捕獲後由交給promise處理返回外部處理
                }
                next(result)
            });
            let res = gen.next(result.value);
            next(res);
        }
    });

}

co(function *gen() {
    let a = yield Promise.resolve(1);
    console.info(a, 'a');
    let b = yield 2;
    console.info(b, 'b');
    let c = yield 3;
    console.info(c, 'c');

}).catch((err)=>{
    console.info(err);
});

Github 歡迎提交PR or ISSUEcode

相關文章
相關標籤/搜索