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 ...
随机推荐
- UBUNTU下MONGODB出现PHP Fatal error: Uncaught exception 'MongoConnectionException' with message 和 Authentication failed on database 'admin' with username
MONGO 远程连接服务器,出现: PHP Fatal error: Uncaught exception Stack trace:# /var/www/data/update_data.php(): ...
- UTF8最好不要带BOM
摘自:http://www.cnblogs.com/findumars/p/3620078.html 几周前还在为BOM的问题苦恼着...正如@梁海所说,“不含 BOM 的 UTF-8 才是标准形 ...
- C51单片机中data、idata、xdata、pdata的区别
C51单片机中data.idata.xdata.pdata的区别 data: 固定指前面0x00-0x7f的128个RAM,可以用acc直接读写的,速度最快,生成的代码也最小. idata: 固定指前 ...
- tomcat启动(三)Catalina分析-load方法分析
load()方法按从上到下顺序分析(主要分析本人所没学过的知识点,其它略过...). Digester类作用 使用sax技术对xml进行解析 未开始解析时Digester.push(this)这个用来 ...
- apache的rewrite规则来实现URL末尾是否带斜杠
1.url: http://www.test.com/user/ 跟:http://www.test.com/user 这两个URL对于用户来说应该是一样的,但从编程的角度来说,它们可以不相同 但我们 ...
- java面试②基础部分
2.1.3 讲一下java中int数据占几个字节 java中有几种基本数据类型? 2.1.4. 面向对象的特征有哪些方面 有四大基本特征:封装.抽象.继承.多态 1)封装,即将对象封装成一个高度自治和 ...
- 关于Win8快速启动失效解决
注册表修改HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager 下BootExecute值为 autocheck空格 ...
- 使用Python制作一个简单的刷博器
呵呵,不得不佩服Python的强大,寥寥几句代码就能做一个简单的刷博器. import webbrowser as web import time import os count=0 while co ...
- 本地启动activemq,报错解决
本地启动activemq时,报错.可以看到是5672端口被占用.在网上查了各种资料,有说是杀掉进程的,有说是禁用Internet Connection Sharing (ICS)服务的,楼主试了都没生 ...
- SpringMVC中异常捕获
如果SpringMVC的action中发生异常,我们想将其跳转到一个固定的错误页面,可以通过applicationContext.xml中增加如下配置实现: <bean class=" ...