function* foo() {
yield 123
};
// - - -
function* foo() {
return yield 123
};
我似乎無法證明兩者之間的區別。JS發電機:「收益率」與「收益率」有什麼不同?
- 是否有顯着差異?
return
應該用在發電機中嗎?
function* foo() {
yield 123
};
// - - -
function* foo() {
return yield 123
};
我似乎無法證明兩者之間的區別。JS發電機:「收益率」與「收益率」有什麼不同?
return
應該用在發電機中嗎?首先,我首先說發電機是一個有點複雜的話題,因此在這裏給出一個完整的概述是不可能的。欲瞭解更多信息,我強烈建議凱爾辛普森的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()
函數將迭代器推進到下一步(關鍵字yield
或return
)。
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
行爲。
希望這有助於!
的區別是最後一個延續調用的結果值:
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
在一起聽起來不太有用。
感謝您的問題,很多答案幫助我瞭解更多關於JS發電機。 – yussan