说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

【探秘ES6】系列专栏:生成器

HTML文档下载 WORD文档下载 PDF文档下载
新一代JavaScript标准,ES6即将发布。【探秘ES6】系列专栏将一一剖析ES6的诸多新特性,让Web开发者对此有清晰全面的了解。本文为系列的第三篇,带你了解ES6的生成器。

ES6作为新一代JavaScript标准,即将与广大前端开发者见面。为了让大家对ES6的诸多新特性有更深入的了解,Mozilla Web开发者博客推出了《ES6 In Depth》系列文章。CSDN已获授权,将持续对该系列进行翻译,供大家学习借鉴。本文为该系列的第三篇。

ES6生成器介绍

什么是生成器呢?

请先看看以下代码。

function* quips(name) {  yield "hello " + name + "!";  yield "i hope you are enjoying the blog posts";  if (name.startsWith("X")) {    yield "it's cool how your name starts with X, " + name;  }  yield "see you later!";}

这是一段有关汤姆猫(talking cat)的代码。它看上去像是一个函数,是吗?在ES6中,它的名字是生成器函数,其与普通函数有很多相似的地方。但有两点不同:

  • 生成器函数以function*开头;
  • 在生成器函数中,yield是一个关键字,如同return。yield可以多次使用,作用是中断生成器,

    而在需要的时候可以恢复生成器的执行

所以生成器函数最大的特点是可以中断自己,但普通函数不可以。

生成器的作用

当使用quips()生成器函数时会出现什么情况呢?

> var iter = quips("jorendorff");  [object Generator]> iter.next()  { value: "hello jorendorff!", done: false }> iter.next()  { value: "i hope you are enjoying the blog posts", done: false }> iter.next()  { value: "see you later!", done: false }> iter.next()  { value: undefined, done: true }

对于普通quips(),它会马上执行直到出现返回或异常抛出等情况。在生成器函数中,调用方式是类似的:quips("jorendorff"),但是它不会马上执行。取而代之的是,它会返回一个已暂停的生成器对象(如上述代码的iter)。你可以把生成器对象看成是一个被暂停的函数调用。要特别说明的是生成器对象在生成器函数开始时被冻结,即第一行代码执行之前。

每当调用生成器对象的.next()方法时,函数恢复运行直至遇到下一个yield表达式,其作用是用于迭代。因此iter.next()的目的是为了返回不同的字符串。在最后的iter.next()中,使用done:true表示结束。到达函数末端意味着返回的结果是undefined,所以代码片段中使用value: undefined结尾。

从技术角度来看,每当生成器执行yield操作时,它的堆栈帧包括本地变量、参数、临时值等都会从堆中被移出。但是生成器对象会保留(拷贝)对该帧的引用,所以.next()可以重新激活它然后继续执行。这里特别要说明的是,生成器不是线程。当一个生成器执行时,它与其调用者都处于同一个线程,是按次序执行而不是并行运行。

可见生成器的作用是暂停本身的运行,然后恢复并继续执行,那么这究竟有何用处呢?

生成器就是迭代器

ES6迭代器不是内建的,可尝试通过使用[Symbol.iterator]()和.next()来进行创建。但是这种类似接口的做法不是最简便的方法。请看下面一个range迭代器例子,它的作用类似于C的for(;;)循环。

// This should "ding" three timesfor (var value of range(0, 3)) {  alert("Ding! at floor #" + value);}

具体的实现代码:

class RangeIterator {  constructor(start, stop) {    this.value = start;    this.stop = stop;  }  [Symbol.iterator]() { return this; }  next() {    var value = this.value;    if (value < this.stop) {      this.value++;      return {done: false, value: value};    } else {      return {done: true, value: undefined};    }  }}// Return a new iterator that counts up from 'start' to 'stop'.function range(start, stop) {  return new RangeIterator(start, stop);}

要查看运行情况请点击这里。

可见迭代器的生成并不是件简单的事情。那么如果采用生成器来实现,应该如何编写呢?

function* range(start, stop) {  for (var i = start; i < stop; i++)    yield i;}

要查看运行情况请点击这里。

对比是很明显的,上述代码仅需4行代码就完成了相同的功能,因为生成器就是迭代器。所有生成器都内建了对.next()和[Symbol.iterator]()的支持,你只需要负责循环的实现就可以了。

除此以外,作为迭代器使用的生成器还可以实现哪些功能呢?

  • 使任何对象可迭代。方法是编写一个生成器函数,然后对每个值进行迭代。然后使用对象的[Symbol.iterator]方法与生成器函数进行绑定。
  • 简化数组功能。如果要实现以数组形式返回函数结果,可以这样写:

// Divide the one-dimensional array 'icons'// into arrays of length 'rowLength'.function splitIntoRows(icons, rowLength) {  var rows = [];  for (var i = 0; i < icons.length; i += rowLength) {    rows.push(icons.slice(i, i + rowLength));  }  return rows;}

如果使用生成器编写,可以把代码简化为:

function* splitIntoRows(icons, rowLength) {  for (var i = 0; i < icons.length; i += rowLength) {    yield icons.slice(i, i + rowLength);  }}

后者与前者的区别是不是一次就计算所有结果并返回一个数组,而是先返回一个迭代器,然后按次序按需进行计算。

  • 返回特殊长度数组。数组是有长度限制的,但是透过生成器迭代特性,可以产生无限的序列。
  • 重构复合循环。当编写一个复杂的循环时,可以提出产生数据的部分,把它改写为一个独立的生成器函数。例如(var data of myNewGenerator(args))。
  • 进行迭代运算的配套工具。ES6并没有提供有关筛选、映射、迭代数据集操作的扩展库。但是借助生成器,我们可以围绕它来简单地创建相关工具。

例如,要在DOM节点上实现与Array.prototype.filter类似的功能,可以这样编写:

function* filter(test, iterable) {  for (var item of iterable) {    if (test(item))      yield item;  }}

可见,生成器真的妙不可言。借助生成器可以方便地实现定制的迭代操作,而迭代是ES6中贯穿始终的新的数据和循环标准。

生成器和异步代码

请看一段代码:

}).on('close', function () {  done(undefined, undefined);}).on('error', function (error) {  done(error);});

异步APIs提供的是错误处理而非异常处理,不同APIs有不同的处理方法。而大多数错误定义是默认的,所以进行异步编程时需要花一定时间去了解。生成器则提供了新的处理方式。

Q.async()是一个实验性的类似于同步代码的异步代码生成方法,请看代码:

// Synchronous code to make some noise.function makeNoise() {  shake();  rattle();  roll();}// Asynchronous code to make some noise.// Returns a Promise object that becomes resolved// when we're done making noise.function makeNoise_async() {  return Q.async(function* () {    yield shake_async();    yield rattle_async();    yield roll_async();  });}

两者的主要区别是异步代码必须使用yield关键字来执行异步函数。因此生成器为新的异步编程模型带来了新的思路,更符合人的思维习惯。

写在最后

限于篇幅,生成器还有两个方法留待后续讲解,.throw()和.return()。多看官方文档多动手练习,你会发现ES6更多精彩。(译者:伍昆 责编:陈秋歌)

原文链接:ES6 In Depth: Generators

本译文遵循Creative Commons Attribution Share-Alike License v3.0 

相关阅读:

【探秘ES6】系列专栏:ES6简介

【探秘ES6】系列专栏:迭代器和for-of循环

欢迎加入CSDN前端交流群:218126086,进行前端技术交流。  

DRM你又赢了:其API纳入HTML5标准 豌豆荚王俊煜:洗白白其实是一个计划外的产物 抢Google等巨头生意,纽约大学小伙挖掘并出售自己数据 noBackend:前端优先的开发模式 C、CPP const 详解 三星5G技术获得突破性进展 未来传输速度可达10Gbps 5月14日:1984年美国社交网站Facebook创办人Mark Zuckerberg出生 Chartkick:一行代码即可绘制出漂亮的图表 用友UAP将打造开放平台 建应用商店销售企业级应用 共享软件营销:如何将你的产品推向海外 谷歌使用Debian Linux作为GCE的默认操作系统 大数据?别唬人了!我们真的需要盲目烧钱追求大数据吗? 日本社交手游公司GREE巨星陨落 中国区全员被裁 战歌:85后手游开发团队背后的故事 分秒钟做款App:细数国内外在线DIY应用网站 指点传媒CEO专访:紧握二三线市场用户命脉 专访Waygo创始人:白切鸡怎么翻译? 探究共享软件海外营销新策略(西安站) 讲师秀8:车音网沈康麒和他的智能驾车服务 数据可视化独领风骚:看这6家初创公司如何玩转大数据? 最新研究显示:IE10防恶意软件能力比Chrome等浏览器都要强 Windows Blue正式定名Windows 8.1 对Windows 8及RT用户免费 Testin云测试破1000万次 自动化测试成趋势 接手Android后首次接受媒体采访 Sundar Pichai谈Android未来 C语言实现二分法查找 让开发者高效编程的10个新框架 Google Analytics中显示访客停留时间为“0”的秘密 大数据之惑 麻省理工三位物理学家自建数据库服务Cloudant 融资1200万美元 网页浏览器进入再造新时代 AMD揭露HSA运算架构新技术hUMA细节 救救我,给100分 NT4.0为主域控制器,有办法降级为独立服务器吗? VBA 如何调用 DotNet's WebService ?? dbexpress为什么在插入带自增长字段时候出错? 为什么不同的查询语句会有不同的效率? 我现在要开发一个游戏大厅,谁能帮我提供一些技术参数>?在线等待。 不是水贴:请求帮助,有上海师范大学的请进 紧急!那位有clearcase winnt 4.2 的注册码,高分相送!!!!! 论坛的表格要在注意什么?《我是个菜》 大家帮忙介绍一本书 帮帮我怎么把系统还原占用的空间还给我——老鸟们帮忙! 过滤问题:Query需要先选择一个表(通过ComboBox)然后从2个Edit内输入两个条件 关于stringgrid的翻页问题 寻找电脑方面的朋友 大家好,帮忙做做这题 大家如何保存自己地提问?? JTable怎样一行一行地显示? 我的程序 无边框窗口显示问题 求教各位大虾 VB数据库 如何知道某字段有这个姓名记录? 我想学一种C++的集成环境,是C++BUILDER还是VC 我完全没基础,请帮我走出第一步:汇编工具在哪下载?我想试试那个“两只老虎” 如何在还原Cookie中的中文字? 制做彩色立体阴影怎么做啊! 我的程序 请问有没有这样的公司? 2000 server 无法使用ADSL????? 我要和她分手。。。。。。。。 一个不错的网站,进来看一下吧! map 使用的几个小问题 請大家幫我做這個的標準譯文,謝謝!!! 就像做考題一樣,不要只說它在概意思! 新手上路第一问!Hello World都不能运行 这样的SQL语句怎样转化成能在mysql下运行的 学汇编,应用在什么地方?单从功能来说,汇编强大还是C++强大 replace语句的使用方法: 一个不错的网站,进来看一下吧! 关于软加密的问题???? 请高手,两个简单的问题?在线等待???急急!!! 关于ADOQuery1.refresh的问题 我的程序 一个不错的网站,进来看一下吧! 求DELPHI开发ACTIVEX用于WEB打印指定内容的实现说明。 dreamweaver中的一个小问题,,,急!急!急! 我的程序 100分求救啊!使用TEvent对象要包含什么头文件啊? 如何使SYNTAXFROMSQL不从RDBMS中的extended attribute system tables中获取数据 一个不错的网站,进来看一下吧! 几个菜鸟问题 求教:如何配准图形和图象 万智牌有关找地的问题我是打纯绿的,我想问有什么牌可以找非基本地,生物或者法术都行. 离子数是怎么算的? 您好,我想问一下,D选项所指的溶液只是氢氧化钙溶液吗?为什么不是氢氧化钙和碳酸钾溶液之和啊?如果D选项只考虑氢氧化钙溶液那B选项为什么要考虑2个溶液的质量呢、?19、下列各组中的物 有一张牌,效果好像是从自己的卡组最上面一张开始翻,直到翻出一张地,对对方造成翻出的卡牌数量的伤害.这是哪张牌? 铁离子的单位电荷怎么算?为什么说每个铁离子带三个正电荷?铁的最外层的电子数是多少?很简单的问题啊......上课没听懂不好意思问同学 帮帮忙啊TAT 几种常见动物毛皮的鉴别 人体内氨基和硝基可以互相转化吗 化合物表示的意义:如naoh 如下图,两个正方形拼在一起,求图中阴影部分的面积 硅烷分解产生硅和氢气,其中的氢气是先形成H原子再变成氢气,还是直接产生的氢气? 选举权作为公民的一项基本政治权利是由哪部法律规定的 分度盘的分度精度和重复精度的单位是什么?如问题补充所示,40”的40后面单位是什么? 电风扇运转会产生磁场吗我做了个显示器散热的风扇,放显示器上但看到显示器出现偏色,怀疑是不是电扇干扰啊,电扇就是电脑电源坼下的电扇 寻求英语听力材料我对听力中的数字不是很敏感,想找一些专门训练数字的听力材料.另外,不知道哪里有那种自动断句的听力材料?哪位朋友有这方面的信息,希望可以告诉我. 加工中心数控分度盘首次使用没松开分度盘就回零了,以后会影响分度的精度吗 完成祖国统一大业的指导方针和法律分别是什么 将过氧化钠固体投入到FeSO4溶液中,开始有白色沉淀生成,接着迅速变为灰绿色,最后变为红褐色.这句话对吗? FeS+HNO3反应会生成S沉淀吗?生成物是什么?(正确式子加配平) "平坦的宇宙"是怎么回事?"四维"是怎样的?别告诉我维空间加一维时间,傻子都知道! FeSo4溶液与NaOH反应生成灰白色沉淀,迅速变成灰绿色,最后变成红褐色.请问灰绿色是怎么来的 为什么说电子发生了转移?要理由! 用什么翻译软件最好.我想将中文翻译成美式英语或英式英语,不要中式英语. 请帮我看看无机化学里弟5小题和弟6小题应该怎么做啊!谢谢!急求! 用5个正方形拼搭而成的物体,从正面看到的是“竖着的两个正方形”,有几种不同的搭法?(画图) 什么软件能将中文翻译成英式英语 ,求解第四题的圈1.和五六小题. "碘酸钾"是不是"碘"? 左看像电风扇,右看像电风扇,虽然像电风扇,就是不会转,请问这究竟是什么? 急等 第十题第三小题 高一化学氧化还原反应一节!含氮废水进入水体对环境造成的污染越来越严重,某课外兴趣小组先测定某废水中含硝酸根离子的离子浓度是3*10的负四次方摩尔每升,而后用金属铝将硝酸根还原为 宇宙空间可以是折叠的吗? 一道无机化学已知标准电极电势,φoCu2+/cu=+0.34V,φoSn4+/ Sn2+=+0.151V.下列离子中,氧化能力最强的是( )A.Sn2+ B.Sn4+ C.Cu D.Cu2+ 在处理的废水过程中为什么突然会变成黄色 宇宙空间能否折叠?一张纸是一个小空间,如果要从它的顶端到底端,直接将它沿着中线对折,两端就可以重合在一起直接到达.那么宇宙大空间是否亦可如此?比如从地球到月球,直接沿它们距离的 婴儿长期在喧闹的环境中对孩子有影响吗3个月的小孩子长期居住在KTV环境中,KTV包间传出的歌声对孩子有影响吗,主要是晚上8点-12点期间,孩子和我们一起居住由于工作原因 印染废水中的黄色怎样去除?我正在做一个污水处理系统,现在的情况是COD已经到了60左右,但是色度还得100多,水呈那种淡黄色,原水是印染废水和发电厂的水,COD1200左右,颜色有时是蓝的,有时是 宇宙折叠说? 急求环境对于孩子的影响英语作文····!急求环境对于孩子的影响英语作文~ 科学兴趣小组在调查一化工厂时,发现有个车间排出的废水澄清透明,呈黄色.为测定该废水中所含的物质,他们进行如下实验(假设能发生的反应均恰好完全反应):(1)用pH试纸测试,测得pH 制约甘肃新疆主产区农作物生长的主要自然条件有哪些 想带孩子去和外面多接触一下~想去一个干净,卫生的环境.给我推荐下 初三化学兴趣小组在调查一化工厂是,发现有个车间排出的废水澄清透明呈蓝色兴趣小组在调查一化工厂是,发现有个车间排出的废水澄清透明呈蓝色为测定该废水中所含的物质,他们进行如下 助听器的数字降噪是什么意思 常用的金属抛光膏有哪几种? 某校化学兴趣小组对附近一化工厂排出的污水进行监测.发现污水中含某些金属离子对水质和环境造成了严重污染.他们曾对该厂排出的污水取样、过滤,对滤液进行了多次检测,其中有三次检测 税收 我巧妙的避开了所有正确答案政治水平测 税收我巧妙的避开了所有正确答案 水溶液在加热时PH值变小的是...答案是氯化钠 可是为什么呢?加热电离强,c(H+)↑ c(OH-)↑ 所以PH↓ 那么盐酸呢? 玉米芽怎么生 低于一个点的税负是什么意思 绣眉注意事项有哪些? 怎样做玉米芽率 是中性词吗 zn(no3)2会和什么反应生成气体 外伤用碘伏好还是酒精外伤口消毒用哪个好? 公民在法律面前一律平等() A.是我国社会主义法实施的基本原则 B.是我国社会主义立法的基本原则 晚上,好端端放在地板上空暖瓶,突然爆炸,暖瓶是老式的铁皮暖瓶.请专家解释. 皮带是什么带动 万智牌问题,米罗地创痕 围攻秘罗地 还有没出的那个新非瑞克西亚 五月份买哪个的补充包 划算?(就是这三个里面那个值钱货多)还有,求新非瑞克西亚牌表(我知道没出,但是有小道消息么? 作为公民,我们可以行使哪些权利? 如果已知英制长度的英尺foot和英寸inch的值,那么对应的米是(foot+inch/12)*0.3048.现在,如果用户输入的是厘米数,那么对应英制长度的英尺和英寸是多少呢?别忘了1英尺等于12英寸.输入格式:输入 普京登顶权力榜刺痛美国 美俄反应冰火日本今日起举行大规模\"夺岛\"演习德清三位工人井底昏倒 民警冒死相救杭州六旬大伯住院期间扇护士耳光赔偿2巴西劫匪持枪入室抢劫不为钱 抢走70美国女童目睹家人被烧死获赔1.5亿美俄八旬老汉熊口脱险油管被凿漏 五千人疏散爆美国国安局入侵雅虎谷歌数据中心黄坤明辞去杭州市人大常委会主任职务 超帅奶爸贝克汉姆宠爱七公主有爱全记录斯诺登莫斯科生活照曝光 休闲打扮未戴日连续监视中国海军动向 我舰队冲绳掉主持人身穿“平”字服道歉金正恩接见朝鲜军人建设者 盛赞其英雄普京治下的“俄式反腐”值得借鉴教皇方济各电话被曝长期遭美国国安局监ABC主持人就辱华言论双手合十鞠躬道港媒:中国将会从美国国家安全局丑闻中菲律宾万圣节举行“重口味”游行(高清日舰强闯我演习区滞留70小时齐跌齐涨局面告一段落!四类个股可关注一个书包的成长血泪史大盘震荡,杠杆型基金成了绞肉机坐五望三,国美在线的逆袭是一个微妙信优衣库火了!优衣库港股最高涨幅4.5羊年春节网购年货有新招:晒家乡特产可杨梅汤给自己的信,心酸!揭秘四川还未被开发的10大世界级海子易享贷CEO赵迪:如果P2P不改变,荔枝果酒“容易宝”成人气王,天弘基金淘宝店销香葱芝士绣球包爱,有时候只需要一个台阶。(男女必看有一种时髦,叫裤子“短一截”深藏不露 李治如何玩转大唐天下?耐克和阿迪相继放弃的智能跑鞋,被李宁独家 | “五根手指心法”教你抓住智中国十大艳遇之城,你去过吗?棕色格纹三件套西装曝狼堡有意曼联前锋埃尔南德斯
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘