ES6-Generator
Generator
关键词:状态机,遍历器,同步方式写异步方法
基本概念
- 形式上,Generator函数是一个普通函数,但是有两个特征。
- function关键字与函数名之间有一个星号。
- 二是,函数体内部使用yield语句,定义不同的内部状态。
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
var h = helloWorldGenerator();
- 调用Generator函数,返回一个遍历器对象,代表Generator函数的内部指针。
// 接上面的demo
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }
yield语句
- yield语句不能用在普通函数中,否则会报错
(function (){
yield 1;
})()
- yield语句如果用在一个表达式之中,必须放在圆括号里面
console.log('Hello' + yield); // SyntaxError
console.log('Hello' + yield 123); // SyntaxError
console.log('Hello' + (yield)); // OK
console.log('Hello' + (yield 123)); // OK
- yield语句用作函数参数或赋值表达式的右边,可以不加括号
foo(yield 'a', yield 'b'); // OK
let input = yield; // OK
return()
- 如果主动调用return()方法,Generator函数将被终结
function* gen(){
yield 1;
yield 2;
yield 3;
}
var g = gen();
g.next() // {value: 1, done: false}
g.return('foo') // {value: 'foo', done: true}
g.next() // {value: undefined, done: true}
- 但是,如果Generator函数内部有try...finally代码块,那么return方法会推迟到finally代码块执行完再执行。
function* gen(){
try{
yield 1;
}finally{
yield 2;
}
yield 3;
}
var g = gen();
g.next() // {value: 1, done: false}
g.return(10) // {value: 2, done: false}
g.next() // {value: 10, done: true}
yield*
- 在一个Generater函数内部直接调用另外一个Generater函数无效
function* outer(){
yield 1;
yield inner();
return 3;
}
function* inner(){
yield 2;
}
var o = outer();
o.next(); // {value: 1, done: false}
o.next(); // {value: inner, done: false}
o.next(); // {value: 3, done: true}
- 上面的情况可以使用
yield*解决
function* outer(){
yield 1;
yield* inner(); // 调用方法与上面不同
return 3;
}
function* inner(){
yield 2;
}
var o = outer();
o.next(); // {value: 1, done: false}
o.next(); // {value: 2, done: false} // 返回结果与上面不同
o.next(); // {value: 3, done: true}
- 任何数据结构只要有Iterator接口,就可以被yield*遍历。
function* demo(){
yield* [1, 2, 3];
}
var d = demo();
d.next(); // {value: 1, done: false}
d.next(); // {value: 2, done: false}
d.next(); // {value: 3, done: false}
d.next(); // {value: undefined, done: true}
- 如果被代理的Generator函数有return语句,那么就可以向代理它的Generator函数返回数据。
function* outer(){
yield 1;
var i = yield* inner();
yield 2 + i;
}
function* inner(){
return 2;
}
var o = outer();
o.next(); // {value: 1, done: false}
o.next(); // {value: 4, done: false}
作为对象属性的Generator函数
- 如果一个对象的属性是Generator函数,可以简写成下面的形式。
let obj = {
* gen(){
yield 1;
}
};
var g = obj.gen();
g.next(); // {value: 1, done: false}
Generator函数的this
应用
- 异步操作的同步化表达,逻辑更清晰
function* render(){
showLoading();
var res = yield getData();
hideLoading();
console.log(res); // 打印ajax的结果
}
function getData(){
$.ajax().done(function(res){
r.next(res);
});
}
var r = render();
r.next();
- 控制流管理,摆脱回调函数多层嵌套
// callback方式
function step(){
step1(function(res1){
step2(res1, function(res2){
step3(res2, function(res3){
console.log(res3);
})
})
})
}
// promise方式
function step(){
step1()
.then(step2)
.then(step3)
.then(function({
// do something
}))
}
// Generator方式
function step(){
var res1 = yield step1();
var res2 = yield step2(res1);
var res3 = yield step3(res2);
}
- 多任务并行。如果yield语句后面的参数,是一个具有遍历器接口的对象,yield会遍历这个对象,再往下执行。这意味着,多个任务按顺序一个接一个执行时,yield语句可以按顺序排列。多个任务需要并列执行时(比如只有A任务和B任务都执行完,才能执行C任务),可以采用数组的写法。
function execTaskA(){
return new Promise(function(resolve, reject){
if(true){
resolve('a')
}
})
}
function execTaskB(){
return new Promise(function(resolve, reject){
if(true){
resolve('b')
}
})
}
function* execTasks(){
var [resA, resB] = yield [execTaskA(), execTaskB()];
// let resB = yield* execTaskB();
console.log(resA, resB);
}
var t = execTasks();
t.next();
- 关于Generator函数的自动执行,可以关注github上的
co组件
ES6-Generator的更多相关文章
- es6 generator函数的异步编程
es6 generator函数,我们都知道asycn和await是generator函数的语法糖,那么genertaor怎么样才能实现asycn和await的功能呢? 1.thunk函数 将函数 ...
- ES6 Generator vs ES6 async/await
ES6 Generator vs ES6 async/await next yield promise refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允 ...
- es6 generator函数
es6 新增了Generator函数,一种异步编程的解决方案 回顾一下,es6 提供了新的遍历方法,for of ,适用于各种数据集合,统一了遍历操作,原生支持for of 集合的数据集合有.数组,字 ...
- ES6 Generator的应用场景
一.基础知识 API文档 ES6 诞生以前,异步编程的方法,大概有下面四种. 回调函数 事件监听 发布/订阅 Promise 对象 Generator 函数将 JavaScript 异步编程带入了一个 ...
- ES6 Generator async
Generator 函数是 ES6 提供的一种异步编程解决方案 async 函数使得异步操作变得更加方便,是 Generator 函数的语法糖. js单线程的原因是:避免DOM渲染冲突! 更新:201 ...
- ES6 Generator 学习笔记一
Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同. Generator 函数有多种理解角度.从语法上,首先可以把它理解成,Generator 函数是一个状态机 ...
- ES6 generator 基础
参考文档 harmony:generators Generator是ES6的新特性,通过yield关键字,可以让函数的执行流挂起,那么便为改变执行流程提供了可能. 创建Generator functi ...
- ES6:Generator函数(1)
Generator函数是ES6提供的一种异步编程解决方案.它会返回一个遍历器对象 function* helloWorldGenerator(){ yield “hello”; yield “worl ...
- es6 --- Generator 函数
第一部分,ES6 中的 Generator 在 ES6 出现之前,基本都是各式各样类似Promise的解决方案来处理异步操作的代码逻辑,但是 ES6 的Generator却给异步操作又提供了新的思路, ...
- ES6 Generator使用
// generator介绍: function* hello() { console.log("hello world") } hello();//没有执行 // 直接调用hel ...
随机推荐
- .NET源码Stack<T>和Queue<T>的实现
这阵子在重温数据结构的时候,顺便用ILSpy看了一些.NET类库的实现,发现一些基本的数据结构的实现方法也是挺有意思的,所以这里拿出来跟大家分享一下.这篇文章讨论的是Stack和Queue的泛型实现. ...
- springboot设置静态资源不拦截的方法
springboot设置静态资源不拦截的方法 springboot不拦截静态资源需配置如下的类: import org.springframework.context.annotation.Confi ...
- Eclipse-离线安装Memory Anlysis Tool
Eclipse版本:Version: Mars.2 Release (4.5.2) 1.从官网下载MAT Memory Anlysis Tool http://www.eclipse.org/mat/ ...
- cygwin 安装.
在线安装, http://www.cygwin.com/ 64位的,下载安装. 先装的低配的,只有几个组件装了,不然全部装太大,下次需要再装... binutils gcc gdb windows ...
- 如何VMare虚拟机里安装Mac操作系统(图文详解)
不多说,直接上干货! 大部分用户玩的是windows,现在,跟随我来玩玩Mac. 1. VMware Workstation 11 2. unlocker 206(for OS X 插件补丁),这是V ...
- php发送get请求
感谢:http://www.zoneself.org/2014/07/21/content_2665.html 1.用PHP发送get请求,很简单: <?php $url='http://www ...
- python总结--目录(转)
python模块 [Python]随机数与随机字符串 举例说明Python的CSV模块 python模块之smtplib: 用python发送SSL/TLS安全邮件 python模块之e ...
- JAVA 导出 Excel, 将Excel下载到本地
昨天说了如何将数据导出成 excel 的两种方式,今天完善一下将 java 导出(文件在服务器)并下载到本地 1. 触发导出 ajax 代码 $.ajax({ type: "POST&quo ...
- 笔记:css3伪选择器改变滚动条样式
现在我打开支持前缀-webkit-的浏览器,也就是说只要支持前缀为-webkit-的浏览器才有效果 <!doctype html> <html lang="en" ...
- Redis高可用升级
前言: 缓存对应实时性要求比较高的业务需求可谓十分重要,但缓存中的实时数据一旦丢失,将直接影响整个业务功能.考虑到各场景的业务需求,redis推出了高可用的方案,即:主从+哨兵的HA机制. 准备 &q ...