発電機とは
- 特殊な関数、特殊なイテレータ (Iterator)
- 定義: 関数名の前にアスタリスクがあり、内部的には yield 構文が使用されます。
- 戻り値: 内部に次のメソッドを含むイテレータ
- 実行: yield キーワードが見つかるまで next() メソッドを呼び出してジェネレーターを消費します。
function * gen(){
console.log('hello generator!')
}
let genResult = gen()
console.log('genResult=',genResult)
デモ: ジェネレーターの反復
function * gen(){
yield "小学生";
yield "中学生"
yield "大学生"
}
for (const v of gen()) {
console.log('v=',v)
}
デモ: 次にジェネレーターが実行されます
- yield のパラメータは next メソッドの戻り値です
- yield はコードを N 個のセクションに分割して実行します
- 次のメソッドはセクション単位で実行できます
function * gen(){
console.log('111')
yield "小学生";
console.log('222')
yield "中学生"
console.log('333')
yield "大学生"
console.log('444')
}
let g = gen()
console.log('g.next()=',g.next())
console.log('g.next()=',g.next())
console.log('g.next()=',g.next())
console.log('g.next()=',g.next())
デモ: ジェネレーター yield の戻り値
- nextメソッドのパラメータはyieldの戻り値です
- N番目のnextメソッドのパラメータはN-1 yieldの戻り値です
function * gen(){
const one = yield "小学生"
console.log('one=',one)
const two = yield "中学生"
console.log('two=',two)
const three = yield "大学生"
console.log('three=',three)
}
const g = gen()
g.next();
g.next('AAA');
g.next('BBB');
g.next('CCC');
デモ: 非同期タスクの同期式
- 要件: 非同期リクエストの結果を順番に取得する
- 順序:ユーザーデータ→注文データ→商品データ
- 非同期: settimout シミュレーションを使用する
function getData() {
let result = []
setTimeout(() => {
result.push('用户数据')
setTimeout(() => {
result.push('订单数据')
setTimeout(() => {
result.push('商品数据')
consumeData(result)
}, 500)
}, 500);
}, 500)
}
function consumeData(data) {
console.log('data=', data)
}
getData()
let result = []
function getUsers() {
setTimeout(() => {
console.log('getUsers...')
result.push('用户数据')
iter.next()
}, 500)
}
function getOrders() {
setTimeout(() => {
console.log('getOrders...')
result.push('订单数据')
iter.next()
}, 500)
}
function getGoods() {
setTimeout(() => {
console.log('getGoods...')
result.push('商品数据')
iter.next()
consumeData(result)
}, 500)
}
function* getData() {
console.log('getData start')
yield getUsers()
yield getOrders()
yield getGoods()
console.log('getData end')
}
function consumeData(data) {
console.log('consumeData data=', data)
}
let iter = getData()
iter.next()
デモ: ジェネレータとイテレータの組み合わせ
const cards = {
suits: ["♣️", "♦️", "♥️", "♠️"],
courts: ["J", "Q", "K", "A"],
[Symbol.iterator]:function*(){
for(let s of this.suits){
for (let i = 2; i < 10; i++) yield s+i
for(let c of this.courts) yield s+c
}
}
}
let result = []
for (const v of cards) {
result.push(v)
}
console.log('result=',result)
console.log('cards=',[...cards])