讲解一下ES6 Generator 函数使用方法

generator是ES6提供的一种异步编程解决方案,在语法上,可以把它理解为一个状态机,内部封装了多种状态。执行generator,会生成返回一个遍历器对象。返回的遍历器对象,可以依次遍历generator函数的每一个状态。同时ES6规定这个遍历器是Generator函数的实例,也继承了Genarator函数的prototype对象上的方法。

Generator 函数组成

Generator 有两个区分于普通函数的部分:

一是在 function 后面,函数名之前有个 * ; 函数内部有 yield 表达式。

其中 * 用来表示函数为 Generator 函数,yield 用来定义函数内部的状态。

functionfunc(){
console.log("one");
yield '1';
console.log("two");
yield '2';
console.log("three");
return '3';
}

执行机制

调用 Generator 函数和调用普通函数一样,在函数名后面加上()即可,但是 Generator 函数不会像普通函数一样立即执行,而是返回一个指向内部状态对象的指针,所以要调用遍历器对象Iterator 的 next 方法,指针就会从函数头部或者上一次停下来的地方开始执行。

f.next();
// one
// {value: "1"donefalse}

f.next();
// two
// {value: "2"donefalse}

f.next();
// three
// {value: "3"donetrue}

f.next();
// {value: undefined, donetrue}

第一次调用 next 方法时,从 Generator 函数的头部开始执行,先是打印了 one ,执行到 yield 就停下来,并将yield 后边表达式的值 ‘1’,作为返回对象的 value 属性值,此时函数还没有执行完, 返回对象的 done 属性值是 false。

第二次调用 next 方法时,同上步 。

第三次调用 next 方法时,先是打印了 three ,然后执行了函数的返回操作,并将 return 后面的表达式的值,作为返回对象的 value 属性值,此时函数已经结束,多以 done 属性值为true 。

第四次调用 next 方法时, 此时函数已经执行完了,所以返回 value 属性值是 undefined ,done 属性值是 true 。如果执行第三步时,没有 return 语句的话,就直接返回 {value: undefined, done: true}。

函数返回的遍历器对象的方法

next 方法

一般情况下,next 方法不传入参数的时候,yield 表达式的返回值是 undefined 。当 next 传入参数的时候,该参数会作为上一步yield的返回值。

functionsendParameter(){
   console.log("strat");
   var x = yield '2';
   console.log("one:" + x);
   var y = yield '3';
   console.log("two:" + y);
   console.log("total:" + (x + y));
}

next不传参

var sendp1 = sendParameter();
sendp1.next();
// strat
// {value: "2"donefalse}
sendp1.next();
// one:undefined
// {value: "3"donefalse}
sendp1.next();
// two:undefined
// total:NaN
// {value: undefined, donetrue}

ext传参

var sendp2 = sendParameter();
sendp2.next(10);
// strat
// {value: "2"donefalse}
sendp2.next(20);
// one:20
// {value: "3"donefalse}
sendp2.next(30);
// two:30
// total:50
// {value: undefined, donetrue}

除了使用 next ,还可以使用 for… of 循环遍历 Generator 函数生产的 Iterator 对象。

return 方法

return 方法返回给定值,并结束遍历 Generator 函数。

return 方法提供参数时,返回该参数;不提供参数时,返回 undefined 。

functionfoo(){
   yield 1;
   yield 2;
   yield 3;
}
var f = foo();
f.next();
// {value: 1, donefalse}
f.return("foo");
// {value: "foo"donetrue}
f.next();
// {value: undefined, donetrue}
throw 方法
throw 方法可以再 Generator 函数体外面抛出异常,再函数体内部捕获。
var g = function* () {
 try {
   yield;
 } catch (e) {
   console.log('catch inner', e);
 }
};

var i = g();
i.next();

try {
 i.throw('a');
 i.throw('b');
} catch (e) {
 console.log('catch outside', e);
}
// catch inner a
// catch outside b

遍历器对象抛出了两个错误,第一个被 Generator 函数内部捕获,第二个因为函数体内部的catch 函数已经执行过了,不会再捕获这个错误,所以这个错误就抛出 Generator 函数体,被函数体外的 catch 捕获。

yield* 表达式

yield* 表达式表示 yield 返回一个遍历器对象,用于在 Generator 函数内部,调用另一个 Generator 函数。

functioncallee() {
   console.log('callee: ' + (yield));
}
functioncaller() {
   while (true) {
       yield* callee();
   }
}
const callerObj = caller();
callerObj.next();
// {value: undefined, donefalse}
callerObj.next("a");
// callee: a
// {value: undefined, donefalse}
callerObj.next("b");
// callee: b
// {value: undefined, donefalse}

// 等同于
functioncaller() {
   while (true) {
       for (var value of callee) {
         yield value;
       }
   }
}

使用场景

实现 Iterator

为不具备 Iterator 接口的对象提供遍历方法。

function* objectEntries(obj) {
   const propKeys = Reflect.ownKeys(obj);
   for (const propKey of propKeys) {
       yield [propKey, obj[propKey]];
   }
}

const jane = { first: 'Jane', last: 'Doe' };
for (const [key,value] of objectEntries(jane)) {
   console.log(`${key}${value}`);
}
// first: Jane
// last: Doe

Reflect.ownKeys() 返回对象所有的属性,不管属性是否可枚举,包括 Symbol。

jane 原生是不具备 Iterator 接口无法通过 for… of遍历。这边用了 Generator 函数加上了 Iterator 接口,所以就可以遍历 jane 对象了。

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/221612.html<

(0)
管理的头像管理
上一篇2025-04-15 02:56
下一篇 2025-04-15 02:58

相关推荐

  • 政企项目IDC服务商怎么选才靠谱,哪家好?

    政企项目筛选IDC服务商,核心在于资质是否齐全、机房是否自营、网络是否稳定、服务是否到位,以及合规是否严密,缺一不可,否则后续隐患巨大,资质审查:从牌照到认证,层层把关政企项目对服务商的要求远超普通企业,资质是第一道硬门槛,多数情况下,IDC服务商需要持有《增值电信业务经营许可证》,且业务覆盖范围必须包含项目实……

    2026-07-27
    0
  • 站群服务器被搜索引擎降权了怎么办,如何恢复权重

    站群服务器被搜索引擎降权,核心原因在于IP关联和内容同质化,解决路径是切断关联、更新内容、更换优质IP段,降权背后的信号:搜索引擎在惩罚什么?IP关联性被识别搜索引擎的算法已经能精准识别同一C段或B段IP下的站点集群,当大量域名解析到同一个IP段,且内容结构相似,蜘蛛会判定为站群操作,IP关联是降权的最直接诱因……

    2026-07-27
    0
  • 网站服务器频繁卡顿如何优化才有效,是什么原因

    网站服务器卡顿的优化没有万能药,但遵循“诊断-硬件-软件-网络-架构”的路径,配合持牌服务商的基础保障,能解决绝大多数性能瓶颈,卡顿原因从哪查?先定位再动手系统资源监控先看服务器自身是否超负荷,登录服务器后,用top或htop查看CPU和内存占用,vmstat观察进程队列和上下文切换,iostat盯着磁盘I/O……

    2026-07-27
    0
  • 服务器被CC攻击,如何快速解决?,怎么办

    当服务器被CC攻击,最快速的解决方法是立即启用高防CDN或WAF进行流量清洗,同时临时封禁高频请求IP并调整应用层限频策略,快速识别CC攻击的典型特征从服务器日志和监控指标入手CC攻击本质是应用层洪水,让服务器处理大量看似合法的请求,你可以通过以下措施快速判断:使用netstat -anp | grep :80……

    2026-07-27
    0
  • 站群服务器IP被封了怎么处理,原因是什么?

    站群服务器IP被封,核心解决思路是:立即排查封禁原因,联系服务商更换IP,同时优化网站内容与行为模式,从根源上降低风险,为什么站群服务器容易遭遇IP封禁?站群服务器本质上是将多个网站集中部署在同一台或同一组服务器上,这种行为模式与传统单站有显著差异,容易触发机房或上游网络的封禁机制,常见封禁诱因违规**:部分站……

    2026-07-27
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注