1. Generator 生成器
2. Generator 基本使用
function *test(){
yield 'a'
yield 'b'
yield 'c'
return 'd'
}
let oG = test()
console.log(oG.next())
console.log(oG.next())
console.log(oG.next())
console.log(oG.next())
四次打印的结果如下:
最后的done是true,表示已经迭代完成
yield 执行机制
function *test(){
let val1 = yield 'a'
console.log(val1)//next方法没有传参打印undefined,有传参数打印 'LOL'
let val2 = yield 'b'
//执行机制以此类推
console.log(val2)
yield 'c'
return 'd'
}
let oG = test()
//第一次next()方法时,代码执行会停留在 yield 'a' 步骤,保存变量 val1 和 console.log(val1)不执行
oG.next()
// 第二次next()方法时,保存变量val1步骤然后执行 console.log(val1)
// val1结果取决于第二次next()传参的参数
oG.next('LOL')
生成器模拟迭代机制:
let obj = {
0 : 'a',
1 : 'b',
2 : 'c',
length : 3,
[Symbol.iterator]:function *(){ //Symbol一种数据结构
let index = 0
while(index != this.length){
yield this[index++]
}
}
}
console.log([...obj]) //['a','b','c']
3. 生成器解决回调地狱的小方案
文件目录结构:
a.txt文件存放b.txt文件的路径;b.txt文件存放c.txt文件的路径 ; c.txt存放着一个字母 c
Promise回调形式:
//node环境执行
const fs = require("fs");
function readFile(path) {
return new Promise((res, rej) => {
fs.readFile(path, "utf-8", (err, data) => {
if (data) {
res(data);
} else {
rej(err);
}
});
});
}
readFile('./a.txt').then((val1)=>{
return readFile(val1)
},(err)=>{
console.log(err)
}).then((val2)=>{
return readFile(val2)
},(err)=>{
console.log(err)
}).then((val3)=>{
console.log(val3)
},(err)=>{
console.log(err)
})
Generator生成器回调基本形式:
//node环境执行
const fs = require("fs");
function readFile(path) {
return new Promise((res, rej) => {
fs.readFile(path, "utf-8", (err, data) => {
if (data) {
res(data);
} else {
rej(err);
}
});
});
}
function *read() {
let val1 = yield readFile("./a.txt");
let val2 = yield readFile(val1);
let val3 = yield readFile(val2);
return val3;
}
let oG = read();
let { value, done } = oG.next();
value.then(val1 => {
let { value, done } = oG.next(val1);
value.then(val2 => {
let { value, done } = oG.next(val2);
value.then(val3 => {
console.log(val3);
});
});
});
两者比较起来,看起来 Generator 的回调形式比较麻烦,所以要对 Generator 进行优化
Generator生成器回调优化
上面Generator生成器回调的代码比较重复,可以用递归的思想去优化
优化:
//node环境执行
const fs = require("fs");
function readFile(path) {
return new Promise((res, rej) => {
fs.readFile(path, "utf-8", (err, data) => {
if (data) {
res(data);
} else {
rej(err);
}
});
});
}
function *read() {//生成器函数
let val1 = yield readFile("./a.txt");
let val2 = yield readFile(val1);
let val3 = yield readFile(val2);
return val3;
}
function co(func){ // 模拟co库的一个小功能
return new Promise((res,rej)=>{
let next = (data)=>{
let {value,done} = func.next(data)
if(done){
res(value)
}else{
value.then((val)=>{ // 递归循环
next(val)
},rej)
}
}
next()
})
}
co( read() ).then((val)=>{
console.log(val) // 打印c
},(err)=>{
})