generator生成器 =》 遍历器 =》 数组 =》 类数组
const likeArray = {0: 'a', 1: 'b', 2:'c', 3: 'd', length: 4}
1. Array.from(likeArray); 转成了数组
2. 给likeArray增加个属性:遍历器 likeArray[Symbol.iterator] = function() {
let i = 0;
return {
next: () => {
return {value:this[i],done: i++ === this.length}
}
}
}
console.log([...likeArray])
likeArray[Symbol.iterator] = function * () { // generator 函数可以产生遍历器
let i =0;
while(i != this.length){
yield this[i++]; //generator固定语法 yield 必须配合着*来使用
}
}
普通函数从头到尾执行
generator函数是es6提供的语法,如果碰到yield就会“暂停”执行,(redux-sage,koa1中)
function * read() { yield 1; yield 2; yield 3; } let it = read() // it 就是迭代器,有个next方法 console.dir(it.next()); // {value: 1, done: false} console.dir(it.next()); // {value: 2, done: false} console.dir(it.next()); // {value: 3, done: true} console.dir(it.next()); // {value: undefined, done: false} // 要想不一个一个写,就写个循环 do{ let {value, done} = it.next(); console.log(value); flag= done; }while(!flag)
应用
function * read() { let a = yield 1; console.log(a); let b = yield 2; console.log(b); let c = yield 3; console.log(c); } //蛇型执行,除了第一次之外的next方法,都是把next中的参数传递给上一次yield的返回结果 let it = read(123) it.next(); //第一次的next传递参数没有任何意义 (执行到第一次的yield 1) it.next(‘2’); // (next中的参数传递给上一次yield的返回结果 a=2,console(a) :2 , 执行到第二个yield ) it.next(‘3’);
用generator实现异步
const fs = require('fs').promises; function * read() { // 代码更像同步的,(执行还是异步的) try{ let name = yield fs.readFile('name.txt', 'utf8'); let age = yield fs.readFile('age.txt', 'utf8') return age }catch(e){ console.log(e) } } let it = read(); let {value, done} = it.next(); value.then(data => { cosole.log(data); let {value, done} = it.next(data); value.then(data => { let {value, done} = it.next(data); console.log(value); }) )