文档章节

ES6中Generator理解

德胜
 德胜
发布于 2015/11/26 16:01
字数 849
阅读 384
收藏 0
点赞 0
评论 0

1. 生成器函数声明

   function*  name(args){};



2. yield使用

function* hello(){
    console.log('before hello');  //可看到hello()并不会立刻执行函数, 到第一次next调用时才会
    var name = yield 'please input your name';  //将字符串传递给第一次next的结果, 并等待接收第二次next传过来的数据.
    yield 'hello : ' + name;  //返回结果给外部的next
    console.log('after hello');
}

var helloer = hello();  //返回生成器实例
console.log(helloer.next());  //开始执行函数, 碰到第一个yield时返回
console.log(helloer.next('haogrgr'));  //接着第一个yield开始执行, 知道第二个yield, 这里通过next传递了参数.
console.log(helloer.next());  //继续执行console.log('after hello');, 并返回done:true, 表示执行完了.

//输出
before hello
Object {value: "please input your name", done: false}   //第一次next调用输出到这里
Object {value: "hello : haogrgr", done: false}                  //第二次next调用输出到这里
after hello                                                                          
Object {value: undefined, done: true}                             //第三次next调用输出到这里


   真实的执行顺序大概为:

1)创建generator实例.

2)第一次调用next方法, 开始执行函数体
第一次 next{
    console.log('before hello');
    return  'please input your name';  //碰到yield, 返回yield后面的值
}

3)next调用返回.  

4)console输出next的返回值  Object {value: "please input your name", done: false}

5)第二次调用next方法, 并传入参数  'haogrgr'.
第二次next{
    var name = 'haogrgr'; //haogrgr通过 next('haogrgr')传过来
    return  'hello : ' + name;  //碰到yield, 返回
}

6)console输出next的返回值  Object {value: "hello : haogrgr", done: false} 

7)第三次调用next
第三次next{
    console.log('after hello');
}

8)console输出next的返回值  Object {value: undefined, done: true}



3. 总结

   1)申明生成器函数使用  function* 开头.

   2)调用生成器函数生成新的生成器实例.

   3)第一次调用生成器next方法, 会开始执行函数, 直到碰到yield关键字.

   4)yield关键字后面可以返回一个值给next调用.

   5)同时, next方法可以有参数, 参数的值会作为   (yield exp)   的值.

   6)yield和next可以看作是通过消息交流的两个组件,  比如 (yield msg) 传递一个消息给next, 然后暂停, 等待下个一个next调用传递一个值作为(yield msg)的返回值.

   7)生成器函数中, return的值, 会作为最后一次next调用的返回值的value属性.

   8)异常可以通过helloer.throw(err)来抛出.



4. 一种实现方式

   1)转义, 比如facebook出的工具regenerator,   对于上面的例子, 会转换为如下的代码.

var marked0$0 = [hello].map(regeneratorRuntime.mark);
function hello() {
    var name;

    return regeneratorRuntime.wrap(function hello$(context$1$0) {
        while (1) switch (context$1$0.prev = context$1$0.next) {
        case 0:
            console.log('before hello');
            context$1$0.next = 3;
            return 'please input your name';
        case 3:
            name = context$1$0.sent;
            context$1$0.next = 6;
            return 'hello : ' + name;
        case 6:
            console.log('after hello');
        case 7:
        case "end":
            return context$1$0.stop();
        }
    }, marked0$0[0], this);
}

var helloer = hello();
console.log(helloer.next());
console.log(helloer.next('haogrgr'));
console.log(helloer.next());


   可以看到, 通过语法转换, 然后加上一个运行时, 成功了实现了生成器的功能.

   通过将函数逻辑分割, 然后再上下文中记录当前的步骤, 来达到控制的转移(原本一路执行到底的函数变成了, 一节一节的跳来跳去的执行).



5. 参考资料

http://www.html5rocks.com/zh/tutorials/es6/promises/

http://www.infoq.com/cn/articles/es6-in-depth-generators

http://www.infoq.com/cn/articles/es6-in-depth-generators-continued

https://facebook.github.io/regenerator/

http://www.zhihu.com/question/30820791

http://swannodette.github.io/2013/08/24/es6-generators-and-csp/

http://swannodette.github.io/2013/07/31/extracting-processes/

http://www.zhihu.com/question/30820791

   


© 著作权归作者所有

共有 人打赏支持
德胜
粉丝 56
博文 31
码字总数 41512
作品 0
长沙
ES6-7

JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMAScript 6 Promises规范为中心,着重向各位读者介绍JavaScr...

掘金官方
01/05
0
0
Generator:同步代码书写异步情怀

编者按:看完本文,你能对ES6的Generator有一个很好的理解,轻松地以同步的方式写异步代码,也能初步理解到TJ大神的co框架的原理。 前言:ES6在2015年6月正式发布,它带给js带来许多新特性,...

有赞前端
2017/08/21
0
0
13篇文章,教你学会ES6知识点

ES6 深入理解ES6》学习笔记 本文用于汇总链接到各个子章节的内容,github 欢迎大家题issues和PR,如果对你有帮助,也可以给 star 支持 :) 目录 第一章 块级绑定 第二章 字符串和正则表达式 ...

你听___
05/08
0
0
JavaScript 异步

JavaScript怎么使用循环代替(异步)递归 问题描述 在开发过程中,遇到一个需求:在系统初始化时通过http获取一个第三方服务器端的列表,第三方服务器提供了一个接口,可通过分页形式获取列表。...

掘金官方
01/02
0
0
Node.js最新Web技术栈(2016年4月)

Node.js最新Web技术栈(2016年4月) 上一次的发布的是精华 Node.js最新Web技术栈(2015年5月),感谢大家喜爱,值此koa2.0发布后,决定再次升级技术栈 Node.js是比较简单的,只有你有前端js基...

i5ting
2016/04/01
5.9K
10
深入浅出 ES6-Generator

深入浅出 ES6-Generator 先不谈概念、定义,我们从实际用例切入。 功能需求 我们现在要做的,是一个基于nodejs+mongoDB的web应用,其中需要一个web页面,显示用户的列表。就这样,需求就这么...

fengwenjie
2015/07/21
0
1
深入理解 ES6

本文篇幅较长,有兴趣的可以先收藏再看。本文将重要的 ES6 特性介绍了一遍,并且详细解释了一些重难点。 let && const 与 的声明用法相同,但是多了一个临时死区(Temporal Distonrtion Zone...

夕阳
2017/09/08
0
0
ES6 Generators 工作原理

编写正确运行的软件可能是困难的,但是我们知道这仅仅是挑战的开始。对一个好的解决方案建模可以把编程从 “可以运行” 转换到 “这样做更好”。相对的,有些事就像下面的注释一样: ////亲爱...

力谱宿云
2016/08/31
209
2
对Koa-middleware实现机制的深入分析

Koa是基于Node.js的下一代web开发框架,相比Express更轻,源码只有几百行。与传统的中间件不同,在Koa 1.x中采用了generator实现中间件,这需要开发者熟悉ES6中的generator,Promise相关知识...

ssssyoki
2017/05/26
0
0
ES6常用知识点概述

前言 国庆假期已过一半,来篇干货压压惊。 ES6,并不是一个新鲜的东西,ES7、ES8已经赶脚了。但是,东西不在于新,而在于总结。每个学前端的人,身边也必定有本阮老师的《ES6标准入门》或者翻...

zimo
2017/10/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

zk实战--rpc框架集群化

在看此篇内容时需要浏览下面内容 netty实战--手写rpc框架 前文功能简介以及功能扩充 利用netty来实现一个点对点的rpc调用。客户端和服务端都是靠手写地址进行socket同学的,无法1对多,也无法...

xpbob
18分钟前
8
0
springboot 发送邮件

获取授权码 添加配置 # 账号和密码spring.mail.username=aaa@qq.comspring.mail.password=bbb# 服务器地址spring.mail.host=smtp.qq.comspring.mail.properties.mail.smtp.ssl.en...

阿豪boy
18分钟前
0
0
如何使用GNU Ring?

文章名:如何使用GNU Ring? 作者:冰焰火灵X 1079092922@qq.com 文章许可:CC BY-SA 4.0 ##1. 安装 下载GNU Ring 点击左边选择你的系统版本(这里以 GNU/Linux 为例,我使用的是Mint 18.3)...

ICE冰焰火灵X
21分钟前
1
0
深入理解springMVC

什么是spring MVC Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而...

Java填坑之路
27分钟前
1
0
《射雕英雄传》书摘

1. 我虽是个飘泊江湖的贫家女子,可不是低三下四、不知自爱之人。你如真心爱我,须当敬我重我。我此生决无别念,就是钢刀架颈,也决意跟定了你。将来……将来如有洞房花烛之日,自然……自能...

k91191
37分钟前
0
0
解决:modal中datePicker 选中时,会触发modal的hidden.bs.modal事件

最近项目中发现了一个bug,具体表现为选中模态框上datepicker组件上的日期时,会触发模态框的关闭事件,导致数据编辑无法正常进行。网上搜索了下,解决方法如下: $('.datepicker').on('hid...

Funcy1122
41分钟前
0
0
Redis分布式锁的正确实现方式

前言 分布式锁一般有三种实现方式: 1.数据库乐观锁 2.基于Redis的分布式锁; 3.基于Zookeeper的分布式锁。本篇博客将介绍第二种方式,基于Redis实现分布式锁。虽然网上已经有各种介绍Redis...

大海201506
今天
1
0
ClassNotFoundException: javax.el.ELManager

这个是因为tomcat7中的el-api2.2,有些版本太低,建议升级tomcat到8.0,利用el-api3.0就会解决这个问题。

无语年华
今天
0
0
Jvm堆内存的划分结构和优化,垃圾回收详解(详细解答篇)

在JVM中堆空间划分如下图所示 上图中,刻画了Java程序运行时的堆空间,可以简述成如下2条 1.JVM中堆空间可以分成三个大区,新生代、老年代、永久代 2.新生代可以划分为三个区,Eden区,两个幸...

嘻哈开发者
今天
1
0
CentOS 7.4 设置系统字符编码

1.语言变量LANG在 /etc/locale 文件中。 2.可以通过/ect/profile 来修改LC_TYPE 变量的值 添加如下代码 export LC_ALL="zh_CN.GBK" export LANG="zh_CN.GBK" 到profile文件中,变量的可以修改...

qimh
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部