Generator是一个状态机,内部封装多个状态 ;
Generator会返回一个遍历器,调用Generator的next方法可以依次执行
(1) function后面跟着*号,调用函数不会立即执行Generator函数,只有调用next方法的时候才会执行. next方法在yield表达式处停止,next返回一个对象,当value是undefined,done是true的时候,就结束了.
(2) next方法可以传入参数,也可以不传入,传入的参数当作上一个yield表达式的返回值 . 这个功能能够在Generator函数运行的各个阶段传入不同的值,进而有不同的行为.
(3) 可以使用for…of循环,到返回done为true时结束,也就是return 的结果不会被for…of捕获
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
// 使用next方法
hw.next(); // {value: "hello", done: false}
hw.next(); // {value: "world", done: false}
hw.next(); // {value: "ending", done: true}
hw.next(); // {value: undefined, done: true}
hw.next(); // {value: undefined, done: true}
// 使用for循环,上面的next方法不能和for...of一起使用,因为状态已经运行过了便固定了
for (let value of hw) {
console.log('value',value);
}
// value hello
// value world
var g = function* () {
try {
yield;
} catch (e) {
console.log('内部捕获', e);
}
};
var i = g();
i.next();
try {
i.throw('a');
i.throw('b');
} catch (e) {
console.log('外部捕获', e);
}
// 内部捕获 a
// 外部捕获 b
遍历器对象上还有一个return的方法,可以结束遍历,即使下面还没有遍历结束 . 返回的参数的value时return方法的参数(如无参数则value=undefined),done为true,
如果Generator内有finally结构,则return方法会被推迟到finally执行完毕后执行
function* numbers () {
yield 1;
try {
yield 2;
yield 3;
} finally {
yield 4;
yield 5;
}
yield 6;
}
var g = numbers();
g.next() // { value: 1, done: false }
g.next() // { value: 2, done: false }
g.return(7) // { value: 4, done: false }
g.next() // { value: 5, done: false }
g.next() // { value: 7, done: true }
在一个Generator的函数内部调用另一个Generator函数,另一个函数返回的是一个遍历器对象
function* bar() {
yield 'x';
yield* foo();
yield 'y';
}
// 等同于
function* bar() {
yield 'x';
yield 'a';
yield 'b';
yield 'y';
}
// 等同于
function* bar() {
yield 'x';
for (let v of foo()) {
yield v;
}
yield 'y';
}
for (let v of bar()){
console.log(v);
}
// "x"
// "a"
// "b"
// "y"
asyn函数就是Generator函数的语法糖,等待await后面的函数完成之后在执行下面的语句 .
async函数返回Promise,
function fun1 () {
setTimeout(()=>{
console.log('fun1');
},2000);
}
function fun2 () {
setTimeout(()=>{
console.log('fun2');
},3000);
}
const asyncFun = async function () {
let f1 = await fun1();
let f2 = await fun2();
console.log(f1);
console.log(f2);
}
asyncFun();
// 2秒后打印fun1
// 3秒后打印fun2
// 返回Promise
async function f() {
return 'hello world';
}
f().then(v => console.log(v))
// "hello world"