es6中generator通俗理解

一、yield可以传参: 

function* show() {
    console.log('a');

    let a = yield 123; // a被gen.next(5)传入5

    console.log(a);

    console.log('b');

    return 23456;
}

let gen = show();

a = gen.next(12); // 返回 { value: 123, done: false }
b = gen.next(5); // 返回 { value: 23456, done: true }

console.log("gen.next(12)");
console.log(a);
console.log("gen.next(5)");
console.log(b);

基本原理:

es6中generator通俗理解

从上面的图上,我们可以看到画红框的地方执行的是我用红笔圈起来的这部分代码,画绿框的地方执行的是用绿笔圈起来的代码。

我们把它简答的看做两个过程,第一个过程传进去的参数是12,第二个过程传递进去的参数是5,所以我们的a接收到的是我们第二个过程里传进去的5。

那么所以通过yield传参的时候,第一个next是废的,传什么都不好使,传什么都白传,这个时候大家可能会问了,那我想给第一个过程传参,该怎么办呢?你说怎么办,不就是我们过去的传参方法嘛,我们传一个num1,一个num2,然后接收一下。

function* show(num1, num2) {
    alert(`${num1}, ${num2}`);
    alert('a');

    let a = yield;
    alert(a);

    alert('b');
}

let gen = show(99, 88);

gen.next(12);
gen.next(5);

这样运行的话,可以正常接收我们传进来的参数。

es6中generator通俗理解

而通过这个过程,我们可以看到,第一个next对于传参来说,是废的,没办法给yield传参的,想给第一个过程传递参数,就得像正常函数一样,通过函数(参数)的形式来。

二、yield可以返回:

咱们刚刚说了yield的第一个功能是可以往里面传东西,下面我们说一说yield的另一个功能,可以往外吐东西(返回)。

咱们在上面把一个大的generator函数划分为几个过程,通过yield来分割这几个过程,我们可以理解为中间结果举个最简单的例子,就像做菜一样。

es6中generator通俗理解

就拿做菜来说,我们可以分为几个步骤:洗菜、切菜、炒菜。

我们可以认为,在最开始输入了刚买回来的菜,也相当于我们函数的参数,接下来的每一步都有一个半成品(刚买回来的菜),它也就相当于我们下一步的输入,最后变成一盘炒好的菜。说白了,在这个函数里,每一步都会有一个中间结果,也算是中间的输入。

从第一步的yield可以传参到第二步的yield有个中间结果,下面我们看一看yield是如何返回的。

function* show() {
    console.log('a');

    let a = yield 123;
    console.log(a);

    console.log('b');

    return 23456;
}

let gen = show();

a = gen.next(12); // 返回 { value: 123, done: false },123为yield 123返回
b = gen.next(5); // 返回 { value: 23456, done: true } // 23456为return 23456返回

console.log("gen.next(12)");
console.log(a);
console.log("gen.next(5)");
console.log(b);

咱们还是和刚才一样,定义一个generator函数,定义两个过程,将next函数的返回值打印出来之后可以看到,第一个过程中返回了{value: 12, done: false},第二个过程返回了{value: undefined, done: true},在第一个过程里,value是12,done是false,done是完成的意思,因为第一个过程并不是函数结束,所以返回的是false,而第二个返回值中,value为什么是undefined呢?

原因很简单,咱们在上面的切菜图上说的很明白了,这个阶段是咱们函数的最后一道工序,最后一道工序就没有yield了,所以也就没有返回值了,想返回东西的话,就只能用return来返回。

上一篇:生成器


下一篇:golang-grpc示例