generator

作者: Rui___ | 来源:发表于2019-11-05 15:11 被阅读0次
    //生成器-->返回值叫迭代器
    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);
      })
    

    相关文章

      网友评论

          本文标题:generator

          本文链接:https://www.haomeiwen.com/subject/ppypmctx.html