2017-02-17 110 views

回答

10

首先,我首先说发电机是一个有点复杂的话题,因此在这里给出一个完整的概述是不可能的。欲了解更多信息,我强烈建议凯尔辛普森的You Don't Know JS系列。第5册(异步&性能)对发电机的输入和输出进行了精彩的讨论。

根据你给出的具体例子!

首先,你的例子写的代码会显示没有区别只有它的正常运行。这里有一个例子:

function* foo() { 
    yield 123; 
} 

function* bar() { 
    return yield 123; 
} 

var f = foo(); 
var b = bar(); 

f.next(); // {value: 123, done: false} 
f.next(); // {value: undefined, done: true} 
b.next(); // {value: 123, done: false} 
b.next(); // {value: undefined, done: true} 

正如你所看到的,我不是像普通函数那样调用生成器。生成器本身返回一个生成器对象(一种迭代器的形式)。我们将该迭代器存储在变量中,并使用.next()函数将迭代器推进到下一步(关键字yieldreturn)。

yield关键字允许我们将值传递给生成器,这就是您的示例运行方式不同的地方。下面是什么样子:

function* foo() { 
    yield 123; 
} 

function* bar() { 
    return yield 123; 
} 

var f = foo(); 
var b = bar(); 

// Start the generator and advance to the first `yield` 
f.next(); // {value: 123, done: false} 
b.next(); // {value: 123, done: false} 

/** Now that I'm at a `yield` statement I can pass a value into the `yield` 
* keyword. There aren't any more `yield` statements in either function, 
* so .next() will look for a return statement or return undefined if one 
* doesn't exist. Like so: 
*/ 
f.next(2); // {value: undefined, done: true} 
b.next(2); // {value: 2, done: true} 

注意foo()将返回undefined作为一种价值,而bar()返回数字2。这是因为我们传递到.next()调用中的值发送到return关键字并设置为返回值。 foo()没有明确的return语句,因此您将获得默认的undefined行为。

希望这有助于!

6

的区别是最后一个延续调用的结果值:

function* fooA() { 
    yield 123 
}; 
var a = fooA(); 
console.log(a.next(1)); // {done:false, value:123} 
console.log(a.next(2)); // {done:true, value:undefined} 

function* fooB() { 
    return 40 + (yield 123) 
}; 
var b = fooB(); 
console.log(b.next(1)); // {done:false, value:123} 
console.log(b.next(2)); // {done:true, value:42} 

大多数发电机不需要return价值,他们的目的是价值流的产生的副作用,当他们正在跑步。所有迭代器都属于这种类型,如果它们运行在for of循环中,则结果仅表示结束,但该值将被丢弃。

然而,还有一些发生器的结果值是重要的,例如,当它们被用作描述异步过程的工具时(在一个polyfill中可以使用async/await承诺语法,或者还有很多其他的东西比如CSP)。在iterable上使用yield*时,您还会得到return ed值。

无论如何,return yield在一起听起来不太有用。