generator yield next

2017-04-12  本文已影响0人  arickxuan
function* outer() {
    console.log('outer: pre yield');
    // 1. yield* inner();
    // 2. yield* inner;
    // 3. yield inner();
    // 4. yield inner;
    console.log('outer: after yield');
}

function* inner() {
    console.log('inner');
}

  1. yield* inner():相当于用inner的内容来替换该位置,不会消耗一次next()调用,inner内的代码会被执行
  2. yield* inner:报错。因为inner是一个generator function,而yield*后面应该是一个igenerator
  3. yield inner():yield的结果是一个generator,消耗一次outer的next()调用,且inner内的代码不会被执行
  4. yield inner:yield的结果是一个generator function,消耗一次outer的next()调用,且inner内的代码不会被执行
function* f1() {
    console.log('f1: pre next');
    yield* f2();
    console.log('f1: post next');
}

function* f2() {
    console.log('  f2: pre next');
    yield* f3();
    console.log('  f2: post next');
}

function* f3() {
    console.log('    f3: pre next');
    console.log('    f3: post next');
}

var g = f1();
g.next();

输出为:

f1: pre next
f2: pre next
f3: pre next
f3: post next
f2: post next
f1: post next

co.wrap(compose(this.middleware))

module.exports = compose;

function compose(middleware) {
    return function*(next) {
        var i = middleware.length;
        var prev = next || noop();
        var curr;

        while (i--) {
            curr = middleware[i];
            prev = curr.call(this, prev);
        }

        yield* prev;
    }
}

function* noop() {}

源码比较简单,其实就是compose([f1, f2, ..., fn])转化为fn(...f2(f1(noop()))),最终的返回值是一个generator function。同时也可以看出,在koa的yield next中,next是一个generator。

下面用compose来对上面的例子进行改写:

function* f1(next) {
    console.log('f1: pre next');
    yield next;
    console.log('f1: post next');
}

function* f2(next) {
    console.log('  f2: pre next');
    yield next;
    console.log('  f2: post next');
}

function* f3(next) {
    console.log('    f3: pre next');
    yield next;
    console.log('    f3: post next');
}

var compose = require('koa-compose');

var g = compose([f1, f2, f3])();
g.next();
g.next();

输出:

f1: pre next
f1: post next

上一篇 下一篇

猜你喜欢

热点阅读