[JS] generator基本使用

cnblogs 2024-07-14 08:11:00 阅读 96

这篇文章介绍了Generator函数的基本使用,包括next方法与yield关键字、throw方法、return关键字及其对应的方法,说明了它们的用法、运行结果和各自的特点,并解析了它们的共同点。

next方法与yield关键字

generator函数可以返回一个迭代器,通过<code>next方法切换generator的状态。

generator函数被调用时并不会执行内部的语句,而是返回一个迭代器对象。

迭代器对象首次调用next方法,才开始执行generator函数的语句。

直到遇到yield语句,内部的执行中断,返回yield关键字右侧表达式的值作为迭代器调用next方法的返回值。

yield语句本身没有返回值,由下一次调用next方法时传入参数作为yield的返回值。

function* gen(){

yield 'hello';

let msg = yield 'world';

console.log(msg);

yield 'end';

}

const g = gen();

console.log(g.next());

console.log(g.next());

console.log(g.next('passing msg'));

console.log(g.next());

输出结果

{ value: 'hello', done: false }

{ value: 'world', done: false }

passing msg

{ value: 'end', done: false }

{ value: undefined, done: true }

throw方法

迭代器对象可以通过调用throw方法向generator函数内部“抛出”异常,在函数内部通过try/catch捕获。

也可以在generator函数内部抛出异常,在调用迭代器方法的位置抛出异常。

向内部抛出异常 - 分类讨论

  1. (理想情况)调用iterator.throw(new Error(...))向内部抛出异常,在内部对应的yield表达式使用try/catch捕获异常;
  2. 如果函数内部没有捕获异常,那么在iterator.throw()语句所在的位置抛出异常;
  3. 如果generator内部和iterator.throw所在位置都没有捕获异常进行处理,那么程序终止;
  4. 还没首次执行next就执行throw,直接在外部调用iterator.throw的位置抛出异常。

向外抛出异常

接下来先看一个向外抛出异常的案例代码:

function* gen(){

yield 1;

throw new Error('inner error');

yield 2;// 不会被执行

yield 3;// 不会被执行

}

const g = gen();

let res;

do{

try{

res = g.next();

console.log(res);

}catch(e){

console.log(e);// 捕获到 'inner error'

}

}while(!res.done);

运行结果:

{ value: 1, done: false }

Error: inner error

{ value: undefined, done: true }

解析:在generator内部使用throw关键字抛出异常,外部调用iterator.next的地方捕获异常,由于generator抛出异常,JS引擎会认为这个generator已经运行结束了,后续的yield不会执行,迭代器的done变为true

return关键字

没有写return语句的 Generator 函数默认在尾部返回undefined

return关键字会返回右侧表达式的值作为next方法的返回值。

return会终止generator,后续的代码都不会执行了,这个特点和普通函数保持一致。

function* gen(){

yield 1;

return 2;

yield 3;

}

const g = gen();

let res;

do{

res = g.next();

console.log(res.value);

}while(!res.done);

执行结果

1

2

return 方法

generator函数返回的迭代器对象还有return方法。

可以在外部手动得到return方法得到的值,并且结束generator。

function* gen(){

yield 1;

yield 2;

yield 3;

}

const g = gen();

console.log(g.next());

console.log(g.return('done'));

console.log(g.next());

运行结果

{ value: 1, done: false }

{ value: 'done', done: true }

{ value: undefined, done: true }

next、throw、return的共同点

这三个方法的本质是让generator函数恢复执行,并且使用不同的语句替换yield表达式。

  • next()yield表达式替换成一个值;
  • throw()yield表达式替换成一个throw语句;
  • return()yield表达式替换成一个return语句。


声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。