良许Linux教程网 干货合集 讲解一下ES6 Generator 函数使用方法

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

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

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

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 对象了。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

img
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部