function* foo() {
yield 123
};
// - - -
function* foo() {
return yield 123
};
両者の違いを示すことはできません。
return
をジェネレータで使用する必要がありますか?最初に、ジェネレーターはやや複雑なトピックであるため、ここで完全な概要を説明することはできません。詳細については、Kyle Simpsonの You Do n't Know JS シリーズを強くお勧めします。 Book 5(Async&Performance)には、ジェネレーターのインとアウトに関する優れた議論があります。
あなたが与えた特定の例に!
最初に、例で記述したコードは違いなしを示しますが、if正しく実行されます。次に例を示します。
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
ループによって実行された場合、結果は単に終わりを示しますが、値は破棄されます。
ただし、結果値が重要なジェネレーターもあります。非同期プロセスを説明するツールとして使用される場合(async
/await
promise構文のポリフィル、またはCSPなどの多くのもの)。イテラブルでyield*
を使用すると、return
ed値も取得します。
いずれにせよ、return yield
を一緒に使用しても、あまり役に立ちません。