Generator是es6引入的,主要用于异步编程。
最大特点是可以交出函数的执行权(即暂停执行)。
它和普通的函数写法有点不同
function关键字与函数名之间有一个*号,以与普通函数进行区别。
它不同于普通函数,是可以==暂停执行==的。
Generator函数体内部==使用yield语句==,可以定义不同的状态。
现在都是状态====数据
yield是异步的分界线,可以把它理解为return。但和return还是存在本质的区别。
先来看一个最简单的==Generator==函数
function* fn() {yield 'a';yield 'b';yield 'c';return 'd';
}
let fn1 = fn();
console.log(fn1.next());
console.log(fn1.next());
console.log(fn1.next());
console.log(fn1.next());// 输出结果:
{ value: 'a', done: false }
{ value: 'b', done: false }
{ value: 'c', done: false }
{ value: 'd', done: true }
要想动起来,我们得使用next方法。每次调用next方法,返回一个对象。
这个对象表示当前的阶段信息。value属性,done属性:返回一个boolean值。其中true表示函数已经执行完了,false表示函数还需要执行。还有下一个next。遇到了return的时候,done
才会返回true。
迭代器
==不同的迭代器指向的指针==是不一样的。例如下面这段代码:
function* fn() {let n = 1;yield ++n;yield ++n;return ++n;
}
let fn1 = fn();
let fn2 = fn();
console.log(fn1.next());
console.log(fn1.next());
console.log(fn2.next());
console.log(fn1.next());
// output
{ value: 2, done: false }
{ value: 3, done: false }
{ value: 2, done: false }
{ value: 4, done: false }
每一个迭代器对象都有专属于自己的指针,每次执行的位置就是==上次迭代器遗留下来==的位置。
==.next()方法==可以接受参数
传入的参数,就是把上次yield语句的返回的值给覆盖了。
第一个yield语句因为在它之前没有yield语句,所以给==第一个yield语句传递参数==是没有意义的!
function* fn() {// 第一次执行开始let _n = 1;let _v = yield _n + 22;console.log("aa-----:" + _v);// 第一次执行结束,第二次结束yield ++_n;// 第二次结束,第三次开始yield ++_n;
}
let fn1 = fn();
console.log(fn1.next());
console.log(fn1.next('abc'));
console.log(fn1.next());
// 注释
/*{ value: 23, done: false }aa-----:abc { value: 2, done: false }{ value: 3, done: false }
*/
Generator函数,支持for of 循环
用来迭代Generator函数在执行时生成的那个迭代对象。
function* fn() {// 第一次执行开始let _n = 1;let _v = yield _n + 22;console.log("aa-----:" + _v);// 第一次执行结束,第二次结束yield ++_n;// 第二次结束,第三次开始yield ++_n;
}
let fn1 = fn();
/* console.log(fn1.next());
console.log(fn1.next('abc'));
console.log(fn1.next()); */
for (let i of fn1) {console.log(i);
}
采用这个打印效果,和上述的三次console.log()结果是一样的。