美文网首页JavaScript
[EcmaScript] yield* next

[EcmaScript] yield* next

作者: 何幻 | 来源:发表于2017-01-09 10:52 被阅读14次

1. iterator和iterable

iterator是一个实现了next方法的对象,
next方法返回一个{value:Anything,done:Boolean}对象。

iterable是一个实现了Symbol.iterator方法的对象,
Symbol.iterator方法方法返回一个iterator

iterator = {
    next: () => ({ value, done })
}

iterable = {
    [Symbol.iterator]: () => iterator
}

2. generator

generator返回的对象,既可以看做是一个iterator,也可以看做是一个iterable

iterator = {

    // iterator
    next: v => ({ value: xxx, done: xxx }),

    // iterable
    [Symbol.iterator]: () => iterator
};

iterator[Symbol.iterator]() === iterator

3. yield与yield*

yield*可以用来yield其他iterable,如果yield*后面不是iterable会报错。

yield* iterable;

4. yield表达式和yield*表达式的值

yield表达式的值,是下一个iter.next的参数值。

let gen = function* () {
  let r = yield 1;
  console.warn(r);    //3
}

let iter = gen();
console.log(iter.next(2));    //{value:1,done:false}
console.log(iter.next(3));    //{value:undefined,done:true}

yield*表达式的值,是yield*后的iterabledonetrue时的value值。

let gen1 = function* () {

  //[{value:1,done:false},{value:2,done:false},{value:3,done:true}]
  let r = yield* gen2();    

  console.warn(r);    //3
}

let gen2 = function* () {
  let x1 = yield 1;
  let x2 = yield 2;
  return 3;
}

let iter = gen1();
console.log(iter.next());    //{value:1,done:false}
console.log(iter.next());    //{value:2,done:false}
console.log(iter.next());    //{value:undefined,done:true} 

5. 使用yeild*串联generator

let gen1 = function* () {
    yield 1;
    yield 2;
}

let gen2 = function* (next) {
    yield 3;
    yield* next;    //yeild* iterable
    yield 4;
}

let gen3 = function* (next) {
    yield 5;
    yield* next;    //yeild* iterable
    yield 6;
}

//将gen1(),gen2(...)用作iterable,将gen3(...)用作iterator
let iter = gen3(gen2(gen1()));

console.log(iter.next());    //{value:5,done:false}
console.log(iter.next());    //{value:3,done:false}
console.log(iter.next());    //{value:1,done:false}
console.log(iter.next());    //{value:2,done:false}
console.log(iter.next());    //{value:4,done:false}
console.log(iter.next());    //{value:6,done:false}
console.log(iter.next());    //{value:undefined,done:true}
console.log(iter.next());    //{value:undefined,done:true}

6. 串联任意多的generator

function compose(gens) {
    return function* (next) {
        if (!next) next = noop();    //next是一个iterable

        let i = gens.length;
        while (i--) {

            //next是一个iterable
            //gens[i]是一个generator,调用后返回一个iterable
            //将上一个next传入gens[i],该gens[i]中就可以yield* next了
            next = gens[i].call(this, next);
        }

        return yield* next;    //yield* iterable
    }
}

function* noop() { }

7. 用例

let gen = compose([gen3, gen2, gen1]);
let iter = gen();

console.log(iter.next());    //{value:5,done:false}
console.log(iter.next());    //{value:3,done:false}
console.log(iter.next());    //{value:1,done:false}
console.log(iter.next());    //{value:2,done:false}
console.log(iter.next());    //{value:4,done:false}
console.log(iter.next());    //{value:6,done:false}
console.log(iter.next());    //{value:undefined,done:true}
console.log(iter.next());    //{value:undefined,done:true}

参考

Github: koajs/compose
iterator和iterable
generator
yield与yield*

相关文章

  • [EcmaScript] yield* next

    1. iterator和iterable iterator是一个实现了next方法的对象,该next方法返回一个{...

  • python yield和yield from用法总结

    python yield和yield from用法总结 yield 作用: 注: generator的next()...

  • python 生成器和协程

    yield 对于python生成器中的yield来说,yield item会产出一个值,提供给next()的调用方...

  • Generator 函数的语法

    函数定义 就是function* name 调用就是.next 每次执行到yield就停止,直接返回yield的内...

  • generator yield next

    yield* inner():相当于用inner的内容来替换该位置,不会消耗一次next()调用,inner内的代...

  • iOS类似async/await的用法

    yield 协程里面重要的关键字yield,在生成的迭代器调用next,每次都会将yield后面的数据返回,并中断...

  • 什么是协程

    协程 to yield 含义:产出和让步。 yield item这行代码会产出一个值,提供给next(...)的调...

  • yield&map&set

    1.yield 使用next来调用yield 2.map map(func,data) 3.set 两个set的交...

  • 协程

    生成器语法 yield 一个对象返回这个对象 暂停这个函数等待下次next重新激活 send与yield的切换...

  • 生成器yield和send

    带有yield的函数即变为生成器,需要用变量来接受,返回genertor对象,next()方法 和__next__...

网友评论

    本文标题:[EcmaScript] yield* next

    本文链接:https://www.haomeiwen.com/subject/ybwcbttx.html