记录高级js学习(十九)生成器及其使用

81 阅读2分钟

生成器是ES6新增的一种函数控制、使用方案,是一种特殊的可以传参的迭代器

通过function后面加个*构造一个生成器

yield后面的值为next执行后返回的done-value对象,参数为value的值

yield赋值的是下一次next传的参数

      // 生成器函数,function后面加个*号  通过yield返回value  
      function* foo(){
        yield 123
        yield 456
        return "结束" //会返回给第三次执行的value
      }
      const generator = foo()
      // next方法返回值为{done,value}
      console.log("第一次执行",generator.next());  //{done:false,value:123}
      console.log("第二次执行",generator.next());  //{done:false,value:456}
      console.log("第三次执行",generator.next());  //没有yield的时候done为true,值为return的内容{done:true,value:"结束"}
      console.log("第四次执行",generator.next());  //继续执行done为true,值为undefined

next()也是可以接收参数的,通过接收yield的返回值获得下一个next携带的参数

      // 生成器函数每一块的参数接收,通过yield赋值接收参数
      function* foo(n){
        console.log('n: ', n);  //100
        const n1 = yield 123
        console.log('n1: ', n1);  //200
        const n2 = yield 456
        console.log('n2: ', n2);  //300
        return "结束" 
      }
      const generator = foo(100)
      // next方法返回值为{done,value}
      // generator.next(101) //第一个next一般是不传参的,没有上层yield 一般在函数执行的时候擦传
      // generator.next(200)
      // generator.next(300)  
      // generator.next(400) 
      
      // 对应也有return和throw方法
      generator.next(101) 
      generator.next(200)
      // {done:true,value:15} 终止生成器,后面next也不执行了
      console.log(generator.return(15)); 
      //抛出异常后 后续代码都不会执行,如果用try catch捕获 那么会执行一次next
      // generator.throw(15)   
      // console.log("111");
      generator.next(300)  
      generator.next(400)  

可以使用生成器来替代迭代器,提高代码效率

      // 生成器来替代迭代器
      function* foo(arr) {
        // for(const item of arr){
        //   yield item
        // }
        // 是上面的语法糖
        yield* arr; //跟上一个可迭代对象

        // 用于替代以下
        // let index = 0;
        // return {
        //   next: () => {
        //     if (index < arr.length) {
        //       //根据done为false返回值
        //       return { done: false, value: this.name[index++] };
        //     } else {
        //       return { done: true, value: undefined };
        //     }
        //   },
        // };
      }
      const arr = [1, 2, 3, 4];
      const generator = foo(arr);

      console.log(generator.next());
      console.log(generator.next());
      console.log(generator.next());
      console.log(generator.next());
      console.log(generator.next());

      // 可迭代对象的可迭代协议用生成器方法
      const objIterator = {
        name: ["abc","def","hij"],
        [Symbol.iterator]:function*(){  //可迭代协议
          yield* this.name
        }
      }
      for(const item of objIterator){
        console.log('item: ', item);
      }