-
Generator
函数介绍 -
Generator
特性 -
Generator
使用场景
什么是Generator
函数?
Generator
函数是解决异步编程一种方案,它可以使函数暂停执行,因此内部封装了多种状态。
在这之前,我们采用回调函数形式处理异步操作。之后出现了Promise
,它解决了回调地狱的问题,但代码冗余也成了它的问题。那另一种方式就是采用Generator
函数。
Generator
函数特性:
我们来看一下Generator
函数的形式:
function* foo() {
yield 'hello';
yield 'IFTS';
return 'end...';
}
这是Generator
函数的定义方式,使用yield
定义状态,return
表示结束。上方函数就代表定义了三个状态。
let f = foo();
console.log(f.next());//{value: 'hello', done: false}
console.log(f.next());//{value: 'IFTS', done: false}
console.log(f.next());//{value: 'end...', done: true}
Generator
函数的执行需要使用next()
方法,遇到yield
就停止执行,并返回一个对象包括当前值和当前状态。
因此Generator
函数区别于普通函数:
- 定义:在函数关键字和函数名之间有星号;
-
yield
关键字:它是暂停执行的标志; - 执行:使用
next()
,并且遇到yield
就停止执行,直到遇到return
代表结束,并将done
改为true
。
遍历Generator
函数:
for (let i of foo()) {
console.log(i);//hello IFTS
}
可以直接只用for..of
遍历,不需要使用next()
。但return
的结果不包含在内。
throw
:
Generator
返回的对象,都有一个throw
方法,可以在函数外抛出,在函数内部捕获。
function* foo() {
try {
yield 'hello';
yield 'IFTS';
} catch (e) {
console.log(e);//error
}
return 'end...';
}
let f = foo();
console.log(f.next());//{value: 'hello', done: false}
f.throw("error");
使用场景:
function r1() {
return new Promise(function (resolve, reject) {
let a = 10;
setTimeout(() => {
if (a > 0) {
t.next(a);
}
})
})
}
function r2() {
return new Promise(function (resolve, reject) {
let b = 10;
setTimeout(() => {
if (b > 0) {
t.next(b);
}
})
})
}
function* task() {
let result1 = yield r1();
console.log("第一个任务-->" + result1);//第一个任务-->10
let result2 = yield r2();
console.log("第二个任务-->" + result2);//第二个任务-->10
}
let t = task();
t.next();
还是Promise中的例子的例子。Generator
函数使程序分段执行,遇到yield
时暂停执行,实现异步操作。