【generatory与iterator】的应用

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);
})
复制代码
相关文章
相关标签/搜索