//生成器-->返回值叫迭代器
function * read(){
yield 1; //产出
yield 2;
yield 3
}
// iterator 迭代器
let it = read();
console.log(it.next()); // {value:1,done:false}
console.log(it.next());
console.log(it.next());
console.log(it.next()); // return unefined
面试题 将类数组转化成数组
function add() {
// ... for of 必须要给当前对象 提供一个生成器方法
console.log([ // ... Array.from
...{
0: 1,
1: 2,
2: 3,
length: 3,
[Symbol.iterator]:function *(){
let index = 0;
while(index !== this.length){
yield this[index++];
}
}
// [Symbol.iterator]() {
// let len = this.length;
// let index = 0;
// // 迭代器 是有next方法 而且方法执行后 需要返回 value,done
// return {
// next: () => {
// return { value: this[index++], done: index === len + 1 };
// }
// };
// }
}
]);
}
add();
function * read(){
try{
let a = yield 1;
console.log(a)
let b = yield 2;
console.log(b)
let c = yield 3;
console.log(c)
}catch(e){
console.log('e:'+e);
}
}
let it = read();
console.log(it.next('xxx')) // {value:1.done:false} 第一次next参数没有任何意义
it.throw('xxx')
用generator 异步读取数据,也得通过返回promise,层层调用。
const fs = require('fs').promises;
function * read(){
let content = yield fs.readFile('./name.txt','utf8'); // age.txt
let age = yield fs.readFile(content,'utf8'); // 10
let xx = yield {age:age + 10}
return xx;
}
let it = read();
it.next().value.then(data=>{
it.next(data).value.then(data=>{
let r = it.next(data);
console.log(r.value);
})
})
解决方式,可以通过co库解决。不用管内部嵌套多少层回调。
let co = require('co');
co(read()).then(data=>{
console.log(data);
});
co库的实现原理
function co(it){
return new Promise((resolve,reject)=>{
// 异步迭代需要先提供一个next方法
function next(data){
let {value,done} = it.next(data);
if(!done){
Promise.resolve(value).then(data=>{
next(data);
},err=>{
reject(err);
})
}else{
resolve(value);
}
}
next();
})
}
async + await 终极方法
const fs = require('fs').promises;
// async + await 查看源码 其实是 generator + co的语法糖
async function read(){ // async函数返回的是promise
//这种方式会产生阻塞,如果希望并发怎么实现?
//let r = await Promise.all([p1,p2]) //可以通过此方式
try{//两种捕获错误方式,1可以用try catch 捕获。2,也可以通过promises捕获
let content = await fs.readFile('./name1.txt','utf8'); // age.txt
let age = await fs.readFile(content,'utf8'); // 10
let xx = await {age:age + 10}
return xx;
}catch(e){
console.log(e);
}
}
read().then(data=>{
console.log(data);
},err=>{
console.log(err);
})
网友评论