iterator 应用
iterator 迭代器 (迭代器有一个next方法,每次调用后都会返回 value,done两个属性)
// 类数组 有长度 有索引 是个对象 能被迭代。 才能使用...扩展运算符
let obj = {0:1,1:2,2:3,length:3}
let arr = [...obj]
console.log(arr);//报错 TypeError: obj is not iterable
// 给一个对象添加迭代器 , 可使他被迭代
// 这个函数执行后返回的是一个迭代器
let obj = {0:1,1:2,2:3,length:3,[Symbol.iterator]:function(){
let self = this;
let index = 0
return { // 迭代器
next(){
return {value:self[index],done:index++ === self.length}
}
}
}}
let ary = [...obj];
console.log(ary)//成功 返回[ 1, 2, 3 ]
复制代码
Generator 应用
// Generator生成器会配合yield 来使用 若是碰到yiled会暂停执行
function* read(){
let a = yield 1; // 产出
let b = yield a;
let c = yield b;
}
//Generator生成器返回的是iterator迭代器 迭代器有next方法 调用next能够返回 value和done
let it = read();
console.log(it)
console.log(it.next(50)) // 第一次next是不能传递参数
console.log(it.next(100))// 第二次传参 执行以后会返回当前的value:100 和done:false
it.next(200) // 第三次传参 执行以后会返回当前的value:200 和done:false
it.next(300) // 第四次传参 执行以后会返回当前的value:300 和done:true 返回true 说明下边没有yield了
复制代码
使用 generator + co 实现 async + await
let fs = require('mz/fs')
function * read(){
let result = yield fs.readFile('./a.txt','utf-8');
let age = yield fs.readFile(result,'utf-8');
let e = yield [age];
return e;
}
function co(it){
return new Promise((resolve,reject)=>{
function next(val){
let {value,done} = it.next(val);
if(done){return resolve(value);}
// 若是不是promise 把他包装成promise
Promise.resolve(value).then(data=>{
next(data);//若是done没有返回true 说明还没完成 递归继续迭代 直到返回true为止
},reject);
}
next();
});
}
co(read()).then(data=>{
console.log(data);
}).catch(e=>{
console.log(e);
})
复制代码