function* foo() {
yield 123
};
// - - -
function* foo() {
return yield 123
};
我似乎无法展示这两者之间的差异。
- 这两者之间是否有可证明的差异?
- 在生成器中应该使用
return
吗?
function* foo() {
yield 123
};
// - - -
function* foo() {
return yield 123
};
我似乎无法展示这两者之间的差异。
return
吗?首先,我要说的是生成器是一个有些复杂的主题,所以在这里提供完整的概述是不可能的。关于更多信息,我强烈推荐 Kyle Simpson 的 You Don't Know JS 系列。第五本书(异步和性能)有关于生成器的详细讨论。
接下来是你提供的具体示例!
首先,你在示例中编写的代码将显示没有区别,但仅当它被正确运行时。以下是一个示例:
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}
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}
f.next(2)
返回值为undefined
,而b.next(2)
返回值为数字2。.next()
调用,它被传递到bar()
生成器中,并作为yield
表达式的结果分配。该表达式出现在return
关键字之后;这意味着我们发送到生成器中的值会被返回并结束生成器。
foo()
没有显式的返回语句,因此您不会得到返回值(foo()
已经产生了它唯一的值,所以生成器已完成,结果是{ done:true, value: undefined }
)。return
值,尽管此答案演示了如何手动使用.next()
获取返回值。bar()
没有返回2
,而是返回了一个Generator
对象(正如您在上面已经指出的那样)。然而,最后的b.next(2)
调用返回一个其value
属性设置为2
的对象。这是因为,在最后一个yield
(即最后的暂停/中断)之后调用next()
时,它会运行函数直到完成,其最终的value
是函数的返回值。 - Domi区别在于最后一个连续调用的结果值:
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
循环运行,则结果只表示结束,但值会被丢弃。
然而,也有一些生成器需要重视结果值,例如当它们用作描述异步进程的工具时(在async
/await
promise语法的polyfill中,或者像CSP这样的其他许多情况)。使用yield*
在可迭代对象上时,还可以获取return
的值。
无论如何,return yield
组合起来并不是非常有用。
yield
执行了两次? - a_a.next(1)
的参数被忽略了。最终结果是通过加上40
和2
得到的。 - Bergiyield …; return
相同的效果,确保在暂停之前至少产生一个值。在后面的例子中,yield
似乎被滥用为 await
的意思,在隐式解包承诺的情况下,在 return
之前是不必要的,但有时可以帮助清晰度或类型正确性。 - Bergiif (paused) { yield i; return; }
。 - Bergi