yieldとreturn
function* fruitGenerator() {
yield 'apple'
yield 'orange'
return 'watermeron'
}
const newFruitGenerator = fruitGenerator()
// ジェネレータの実行が開始され、先頭のyieldまで実行される
// yieldに到達した時点でジェネレータの実行は停止され、戻り値appleを呼び出し元に返す
console.log(newFruitGenerator.next())
// ジェネレータの実行が再開され、2つ目のyieldまで実行される
// yieldに到達した時点でジェネレータの実行は停止され、戻り値orangeを呼び出し元に返す
console.log(newFruitGenerator.next())
// ジェネレータの実行が再開され、returnまで実行される
// returnに到達した時点でジェネレータの実行は完了し、戻り値watermeronを呼び出し元に返す
// この時、結果オブジェクトのdoneフラグがtrueになる
console.log(newFruitGenerator.next())
console.log(newFruitGenerator.next())
// 結果:
/**
{ value: 'apple', done: false }
{ value: 'orange', done: false }
{ value: 'watermeron', done: true }
{ value: undefined, done: true }
*/
ジェネレータによるイテレータ生成
function* iteratorGenerator(arr) {
for (let i = 0; i < arr.length; i++) {
yield arr[i]
}
}
/* -------------------------------------------------------------------------- */
const iterator = iteratorGenerator(['apple', 'orange', 'watermelon'])
let currentItem = iterator.next()
while (!currentItem.done) {
console.log(currentItem.value)
currentItem = iterator.next()
}
// 結果:
/**
apple
orange
watermelon
*/
ジェネレータに値を渡す
function* twoWayGenerator() {
const what = yield null
console.log('Hello' + what)
}
/* -------------------------------------------------------------------------- */
const twoWay = twoWayGenerator()
twoWay.next()
twoWay.next('World')
// 結果:
/**
HelloWorld
*/
ジェネレータを使った非同期処理の制御
コールバックを利用するパターン
function asyncFlow(generatorFunction) {
function callback(err) {
if (err) {
return generator.throw(err)
}
const results = [].slice.call(arguments, 1)
generator.next(results.length > 1 ? results : results[0])
}
const generator = generatorFunction(callback)
generator.next()
}
/* -------------------------------------------------------------------------- */
const fs = require('fs')
const path = require('path')
// 自分自身が記述されたファイルのクローンを作成する
asyncFlow(function* (callback) {
const fileName = path.basename(__filename)
const myself = yield fs.readFile(fileName, 'utf8', callback)
yield fs.writeFile(`clone_of_${fileName}`, myself, callback)
console.log('Clone created')
})
// 結果:
/**
Clone created
*/