资讯专栏INFORMATION COLUMN

Javascript中的Generator函数和yield关键字

ZHAO_ / 3091人阅读

摘要:序在中,大家讨论的最多的就是异步编程的操作,如何避免回调的多次嵌套。今天所讲的和就是和异步编程有关,可以帮助我们把异步编程同步化。然而这样的方法依然需要依赖外在的库函数,于是中提出了和关键字。

在Javascript中,大家讨论的最多的就是异步编程的操作,如何避免回调的多次嵌套。异步操作的回调一旦嵌套很多,不仅代码会变的臃肿,还很容易出错。各种各样的异步编程解决方案也被不断提出,例如大家所熟知的Promise,co等等。今天所讲的Generator和yield就是和异步编程有关,可以帮助我们把异步编程同步化。

Generator简介

Generator在形式上和函数差不多,只是在function和函数名之间多了一个*。Generator内部必须使用yield关键字。例如:

function * gen(){
  var result1 = yield "hello";
  var result2 = yield "world";
  return result1 + result2;
}

当调用Generator函数时,并不会执行函数内部的代码,而是返回一个遍历器,该遍历器包含一个next方法。每次执行next方法,Generator函数体会开始执行,直到遇到yield语句,执行该语句并在此暂停。用法如下:

var g = gen();
g.next(1);
//{value : "hello", done : false}
g.next(2);
//{value : "world", done : false}
g.next();
//{value : 3, done: true}
g.next();
//{value : undefined, done: true}

调用next方法会返回一个对象,这个对象包含两个属性,value和done,value即是当前yield语句的值。done表示Generator函数体是否被执行完。next方法同时接受一个参数,这个参数会作为yield语句的返回值,可以被后面的程序所使用。当程序执行完或者遇到return语句,value即为函数体的返回值,done就变成了true。至此,如果再执行next方法,value就为undefined, done依然是true。

Generator在遍历中的应用

在js中,我们要遍历一个数组,我们可以用for...of这样的语句来进行遍历,这其实也是因为数组中包含了一个Generator遍历器。如果我们的自己定义的对象也包含一个遍历器,我们也就可以通过for...of等遍历语句来遍历自定义的对象。这个遍历器被存在Symbol.iterator属性中。

var myArray = {
  0: "你",
  1: "的",
  2: "名字",
  length: 3
};

myArray[Symbol.iterator] = function * (){
  for(var i = 0; i < this.length; i++) {
    yield this[i];
  }
};

for(var item of myArray) {
  console.log(item);
}
//你
//的
//名字
Generator在异步编程中的应用

Javascript的核心就是异步编程,每个异步操作都会提供一个callback回调函数来返回执行的结果。假设我们有几个操作,后一个操作依赖前一个操作的结果,如果采用回调的方式:

step1(function(value1) {
  step2(value1, function(value2) {
    step3(value2, function(value3)) {
      //some code
    }
  });
})

这样的代码一单回调的嵌套变多,会让程序变的非常难理解,同时也很容易出错。我们要做的就是将回调变的扁平化。Promise对象就是这样的功能,将上述的操作Promise化:

step1().then(function(value1){
  return step2(value1);
}).then(function(value2){
  return step3(value2);
}).then(function(){
  //some code
})

我们可以看到嵌套变少了,但是这并不是最理想的解决方案,如果我们能将异步操作变成同步操作那样,即没了嵌套,程序也会变的好理解。Generator函数就给我们提供的这样的机会。

function *workflow(){
  var value1 = yield step1();
  var value2 = yield step2();
  var value3 = yield step3();
  //some code
}

这样就是我们希望结果,异步编程编程了同步编程的形式。我们接下来要做的是让这个Generator执行起来,所以我们需要一个执行器。co就是一个执行器,让Generator自动执行。

co(function *workflow(){
  var value1 = yield step1();
  var value2 = yield step2();
  var value3 = yield step3();
  //some code
});

co有个限制,yield语句后面跟的只能是Promise对象或者Thunk函数,关于co更详细的介绍,可以参考阮老师的文章co 函数库的含义和用法。然而这样的方法依然需要依赖外在的库函数,于是ES6中提出了async和await关键字。async和await其实就是Generator的语法糖。只是它自带执行器。将上面的代码改写成async形式:

async function workflow(){
  var value1 = await step1();
  var value2 = await step2();
  var value3 = await step3();
  //some code
}

var result = workflow();

async没有了co的限制。await关键字后面可以跟 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88031.html

相关文章

  • JavaScript异步编程:Generator与Async

    摘要:从开始,就在引入新功能,来帮助更简单的方法来处理异步编程,帮助我们远离回调地狱。而则是为了更简洁的使用而提出的语法,相比这种的实现方式,更为专注,生来就是为了处理异步编程。 从Promise开始,JavaScript就在引入新功能,来帮助更简单的方法来处理异步编程,帮助我们远离回调地狱。 Promise是下边要讲的Generator/yield与async/await的基础,希望你已...

    leon 评论0 收藏0
  • 《Node.js设计模式》基于ES2015+的回调控制流

    摘要:以下展示它是如何工作的函数使用构造函数创建一个新的对象,并立即将其返回给调用者。在传递给构造函数的函数中,我们确保传递给,这是一个特殊的回调函数。 本系列文章为《Node.js Design Patterns Second Edition》的原文翻译和读书笔记,在GitHub连载更新,同步翻译版链接。 欢迎关注我的专栏,之后的博文将在专栏同步: Encounter的掘金专栏 知乎专栏...

    LiuRhoRamen 评论0 收藏0
  • JavaScriptGenerator理解使用

    摘要:返回的遍历器对象,可以依次遍历函数内部的每一个状态。下一步,必须调用遍历器对象的方法,使得指针移向下一个状态。从语义上讲,第一个方法用来启动遍历器对象,所以不用带有参数。 Generator理解 Generator 函数是 ES6 提供的一种异步编程解决方案,可以这么理解: 从语法上,首先可以把它理解成,Generator 函数是一个状态机,封装了多个内部状态。执行 Generato...

    seal_de 评论0 收藏0
  • 异步流程控制:7 行代码学会 co 模块

    摘要:而在中是迭代器生成器,被创造性的拿来做异步流程控制了。当执行的时候,并不执行函数体,而是返回一个迭代器。行代码再看看文章开头的行代码首先生成一个迭代器,然后执行一遍,得到的是一个对象,里面再执行。 广告招人:阿里巴巴招前端,在这里你可以享受大公司的福利和技术体系,也有小团队的挑战和成长空间。联系: qingguang.meiqg at alibaba-inc.com 首先请原谅我的标题...

    tinna 评论0 收藏0
  • ES6学习笔记之Generator函数

    摘要:调用函数后和普通函数不同的是,该函数并不立即执行,也不返回函数执行结果,而是返回一个指向内部状态的对象,也可以看作是一个遍历器对象。第一个只是用来启动函数内部的遍历器,传参也没有多大意义。 之前断断续续接触到了一些ES6的知识,异步编程方面听得比较多的就是Promise,直到最近比较系统地学习了ES6的新特性才发现Generator这个神奇的存在,它可以实现一些前所未有的事情,让我顿时...

    cjie 评论0 收藏0

发表评论

0条评论

ZHAO_

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<