LoginSignup
0
0

More than 3 years have passed since last update.

【javascript】ジェネレータ関数

Last updated at Posted at 2020-07-14

こちらの記事は以下の書籍を参考に執筆しました

ジェネレータ関数

//ジェネレータ関数にはアスタリスクが付いている。
function *myGeneratorFunction(){
  //...
}

//ジェネレータ関数の呼び出しではnewを使用しない
const myGenerator=myGeneratorFunction()

出典:入門JavaScriptプログラミング

const myObj={
  *myGen(){//オブジェクトリテラルでの簡潔なジェネレータメソッド
    //..
  }
}

出典:入門JavaScriptプログラミング

イールディング

ジェネレータ関数内のコードは通常の関数と同じように動作するが、1つ大きな注意点がある。
javascriptでは関数の内側で飲み使えるyieldが追加されている。
これにより関数内側と外側との間に双方向の通信チャンネルが作成される。

関数の実行はyieldが検出されたとことで中断、その関数を呼出した外側のコードに制御が戻される。
yieldを使用するときは、returnと同様に外側のプロセスに値を渡すこともできる。

function* myGeneratorFunction(){
  //...
  const message='Hello';
  yield message;//実行はここで中断し、外側のプロセスに'Hello'が返される
}

出典:入門JavaScriptプログラミング

yieldは実際には式であり、関数内であとから使用する値を取得できる。

function* myGeneratorFunction(){
  //...
  const message='Hello';
  yield message;//外側からのプロセスからの値を補足
  //...
}

出典:入門JavaScriptプログラミング

ジェネレータ関数の使用

ジェネレータ関数を呼び出すと、新しいジェネレータオブジェクトが返される。このジェネレータオブジェクは最初は停止状態で、nextメソッドを呼び出すまで何もしない。

function* myGeneratorFunction() {
  connsole.log('This code is now running')
}

myGeneratorFunction() //この時点ではlogは評価されない

const myGenerator = myGeneratorFunction(); //ここでも評価されない。

myGenerator.next(); //ようやく評価される。

出典:入門JavaScriptプログラミング

yieldがある場合は呼び出しまで何もしない

function* myGeneratorFunction() {
  console.log('A')
  yield;
  console.log('B')
}
const myGenerator = myGeneratorFunction();

myGenerator.next(); //A
myGenerator.next(); //B

出典:入門JavaScriptプログラミング

nextメソッドを呼び出すたびにvalueとdoneの2つのプロパティを持つオブジェクトが返される。

プロパティ 説明
value yieldに渡された値を含んでいる。
done ジェネレータが中断状態7日終了したのかを示す。

出典:入門JavaScriptプログラミング

function* myGeneratorFunction() {
  console.log('Started')
  let recievedA = yield 'a'
  console.log('recievedA:', recievedA)
  let recievedB = yield 'b'
  console.log('recievedB:', recievedB)
}
const myGenerator = myGeneratorFunction();
let gotA = myGenerator.next(0); //Started
console.log('gotA', gotA) //gotA {value: "a", done: false}
let gotB = myGenerator.next(1); //recievedA: 1
console.log('gotB', gotB) //gotB {value: "b", done: false}
let gotC = myGenerator.next(2); //recievedB: 2
console.log('gotC', gotC) //gotC {value: undefined, done: true}

出典:入門JavaScriptプログラミング

ジェネレータ関数から最後に返されたオブジェクトのdoneプロパティにはtrueが設定されて、valueがundefinedになっている。

また、最初のnext呼び出しに渡された0が使用されない。これは最初のnextが以降のようにyieldに関連付けられていないため。

最初のnext呼び出しはジェネレータを初期状態から呼び起こすためのもの。

まとめ

  • ジェネレータ関数はアスタリスクで定義
  • ジェレネータ関数はジェネレータオブジェクトを返す
  • ジェレネータはyieldで値を返せる
  • nextで次の処理を実行できる
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0