一、简介
Generator函数是ES6引入的新型函数,用于异步编程,跟Promise对象联合使用的话会极大降低异步编程的编写难度和阅读难度。
与普通函数的区别:
- function关键字与函数名之间有一个星号;
- 函数体内部使用yield语句,定义不同的内部状态(yield在英语里的意思就是“产出”)。
二、简单示例
1、yield和return
function* Foo() {
yield 'hello';
yield 'world';
return '!';
}
var foo = Foo();
console.log(foo.next());
console.log(foo.next());
console.log(foo.next());
注意:generator函数不能直接使用,是通过next()方法获取yield/return的返回结果,而return可以提前终止函数。foo.return('!')方法也可终止函数。
2、yield*
字符串方式
function* Foo() {
yield* 'hello';
}
var foo = Foo();
console.log(foo.next());
console.log(foo.next());
console.log(foo.next());
console.log(foo.next());
console.log(foo.next());
console.log(foo.next());
打印结果:
数组方式
function* Foo() {
yield* ['a', 'b', 'c'];
}
var foo = Foo();
console.log(foo.next());
console.log(foo.next());
console.log(foo.next());
console.log(foo.next());
打印结果:
3、与for of配合使用
yield和return
function* Foo() {
yield 1;
yield 2;
return 3;
}
var foo = Foo();
for(var v of foo) {
console.log(v);
}
打印结果:
从上可以看出for of不执行return值
yield*
function* Foo() {
yield* 'hello';
}
var foo = Foo();
for(var v of foo) {
console.log(v);
}
打印结果:
4、throw方法
function* Foo() {
try {
yield;
} catch(e) {
console.log('内部捕获', e);
}
}
var foo = Foo();
foo.next();
try {
foo.throw('a');
foo.throw('b');
} catch (e) {
console.log('外部捕获', e);
}
三、配合Promise使用
function promiseFn() {
new Promise(function(resolve, reject) {
setTimeout(function() {
foo.next('G');
}, 1000);
});
}
function* Foo() {
var a = yield promiseFn();
var b = yield promiseFn();
console.log(a, 111);
console.log(b, 222);
}
var foo = Foo(); // foo是全局变量,挂在window上,存在变量提升,在执行到promise异步的时候,可以直接使用
foo.next();
四、配合ajax使用
demo.php
<?php
header('content-type: application/json');
$a = ['name'=>'tom','age'=>rand()];
echo json_encode($a);
demo.html
function ajax() {
$.ajax({
type: 'get',
url: 'demo.php',
success: function(res) {
foo.next(res);
},
error: function(error) {
foo.next(error);
}
});
}
function* Foo() {
var a = yield ajax();
var b = yield ajax();
console.log(a, 111);
console.log(b, 222);
}
var foo = Foo();
foo.next();
打印结果:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。