Generator函数与co

本文的示例代码参考co

目录

  • Generator

  • co

  • Source-Code

Generator

function* foo() {
    yield console.log('1');
    yield console.log('2');
}

var g = foo();
g.next(); // 1
g.next(); // 2

更多关于Generator函数可以参考Generator 函数的语法

co

cnpm i --save co
var co = require('co');

function* foo() {
    yield Promise.resolve(console.log('1'));
    yield Promise.resolve(console.log('2'));
}

co(foo); // 1 2

co适用于: Generator函数的yield命令后面 只能是Thunk函数或Promises对象

Source Code

  • co实现的核心代码只有以下的区区40行
function co(gen) {
    var ctx = this;
    var args = slice.call(arguments, 1);

    return new Promise(function (resolve, reject) {
        if (typeof gen === 'function') gen = gen.apply(ctx, args);
        if (!gen || typeof gen.next !== 'function') return resolve(gen);

        onFulfilled();

        function onFulfilled(res) {
            var ret;
            try {
                ret = gen.next(res);
            } catch (e) {
                return reject(e);
            }
            next(ret);
            return null;
        }

        function onRejected(err) {
            var ret;
            try {
                ret = gen.throw(err);
            } catch (e) {
                return reject(e);
            }
            next(ret);
        }

        function next(ret) {
            if (ret.done) return resolve(ret.value);
            var value = toPromise.call(ctx, ret.value);
            if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
            return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
                + 'but the following object was passed: "' + String(ret.value) + '"'));
        }
    });
}

function toPromise(obj) {
    if (!obj) return obj;
    if (isPromise(obj)) return obj;
    if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj);
    if ('function' == typeof obj) return thunkToPromise.call(this, obj);
    if (Array.isArray(obj)) return arrayToPromise.call(this, obj);
    if (isObject(obj)) return objectToPromise.call(this, obj);
    return obj;
}

更多关于co的源码可以参考co/index.js

  • 完整的流程示意图如下
co-logic-01.png

更多关于Promise可以参考Promise 对象

参考

  • co.js - 让异步代码同步化

  • co 函数库的含义和用法

  • 神奇的co

你可能感兴趣的:(Generator函数与co)