js生成器

发布于:2025-07-24 ⋅ 阅读:(19) ⋅ 点赞:(0)


概念

生成器是 ES6 中新增的一种特殊的函数,所以也称为“生成器函数”。它可以更灵活地控制函数什么时候执行, 什么时候暂停。

生成器是一种特殊的迭代器

返回值
调用生成器函数返回一个新的对应的生成器,
通过生成器next方法可以控制其迭代,next方法则返回下一个状态的生成器

由于生成器是一种特殊的迭代器,故生成器的属性与其类似
如下
{value: '', done: false}
其中 value为值,done则是是否完成迭代

生成器函数

定义一个生成器函数,我们需要在function单词和函数名之间加一个*符号

function* fn() {  } 

yield关键字
在生成器函数中通过yield来分割,每当执行时会暂停到下一个yield

(与yield同行的会被执行后暂停)

而value值可以通过 yield 赋予的值赋值
举例如下

function* fn(){
      console.log(1);
      yield
      console.log(2);

      yield console.log(3);
      console.log(4);
      
    }
    const f=fn()
     console.log(f.next());//输出1  {value:undefined , done: false}
    console.log(f.next());//输出2和3 {value:undefined , done: false}
    console.log(f.next());//输出4 {value:undefined , done: true}

当通过yield赋值时,yield就不能与其他执行代码同行,否则会报错

或者加,隔开。但与yield也不会执行,会归为下一步骤

如下

function* fn(){
      console.log(1);
      yield 0
      console.log(2);

      //yield '1' console.log(3);会报错
      yield '1'
      console.log(3)
      console.log(4);
      
    }
    const f=fn()
    console.log(f.next());//1  {value:0 , done: false}
    console.log(f.next());//2      {value:'1' , done: false}
    console.log(f.next());//3和4    {value:undefined , done: true}

next的参数
next的参数会将值传给当前阶段(未执行当前next时)的所暂停的yield
如下

function* fn(){
     console.log(yield );
     console.log(yield);
     console.log(yield);
    }
    const f=fn()
    f.next(1)//不会被输出,因为第一次执行时没有暂停在yield
    f.next(2)//输出
    f.next(3)//输出
    f.next(4)//输出
    f.next(5)//已经迭代完成了,故不会输出

可以看出,有效的next方法个数就是yield+1个

如何中途结束生成器的执行

有三种方式:

  • 方式1:return 语句。(与函数执行完则会结束同理)
  • 方式2:通过生成器的 return() 函数。
  • 方式3:通过生成器的 throw() 函数抛出异常

return的参数会返回给生成器的value

function* fn(){
     console.log(yield );
     console.log(yield);
     console.log(yield);
    }
    const f=fn()
    f.next(1)
    f.next(2)
    console.log( f.return(3));// {value:3 , done: true}
    f.next(4)//已结束不会触发
function* fn(){
     console.log(yield );
     console.log(yield);
     console.log(yield);
    }
    const f=fn()
    f.next(1)
    f.next(2)
    console.log( f.throw(new Error('next2 error')));//Uncaught Error: next2 error
    f.next(4)

使用 yield* 迭代可迭代对象

function* f(arr) {
  for (const item of arr) {
    yield item;
  }
}

const myArr = ['a', 'b', 'c'];
const b = f(myArr);
console.log(b.next());
console.log(b.next());
console.log(b.next());
console.log(b.next());
///替换为
function* f(arr) {
  yield* arr;
}

const myArr = ['a', 'b', 'c'];
const arrGenerator = f(myArr);
console.log(b.next());
console.log(b.next());
console.log(b.next());
console.log(b.next());


网站公告

今日签到

点亮在社区的每一天
去签到