一.generator函数的大致介绍
generator函数是es6引入的,主要用于异步编程
generator最大特点是交出函数的执行权(即暂停执行,通过yield实现该功能)
二.与普通函数写法的不同:
1. 函数名之前有个星号,以示区别
它不同于普通函数,是可以暂时执行的
2.generator函数体内部使用yield语句
yield语句只能在generator语句中使用,普通函数不行。现在比较流行数据驱动视图,yield语句可以定义不同的内部数据。
本质上,整个generator函数就是一个封装的异步任务。yield命令是异步不同阶段的分界线,所以说,有时也会把yield当做return。当然了,yield跟return有本质的不同。
示例1:.next()的使用
普通函数是通过调用函数的形式,但generator函数要让它动起来,需要用`.next()`方法,我们可以理解为是一个“启动方法”,作用是分阶段的执行generator函数。
每次调用.next()方法,会返回一个对象,表示当前阶段的信息,value属性,done属性:true表示函数已经执行完了,false表示函数还没执行完。
<script type="text/javascript">
//普通函数
function xxfn(){
console.log('xxfn函数')
}
xxfn()
//定义generator函数
function* xxfn(){
yield 'a';
yield 'b';
yield 'c';
return 'd end...'
}
var _xxfn = xxfn()
//第一个yield语句
console.log(_xxfn.next())//{value: 'a', done: false}
//第二个yield语句
console.log(_xxfn.next())//{value: 'b', done: false}
//第三个yield语句
console.log(_xxfn.next())//{value: 'c', done: false}
//第四个是return,done的值为true
console.log(_xxfn.next())//{value: 'd', done: false}
//后面,这时value的值就是undefined,就没有意义了
console.log(_xxfn.next())
</script>
示例2:迭代器对象
每当你调用了一个迭代器nebula的.next()方法,generator函数内部的指针,就是从上一次停下的地方继续运行,直到遇到下一个yield语句。每个迭代器之间是相互独立的,作用域独立
那为什么说是迭代器对象呢?
因为他得把里面的yield语句都走一遍,yield就像录音机上的暂停键,next就像录音机上的继续键。
<script type="text/javascript">
function* xxfn() {
var _n = 1;
yield ++_n;
yield ++_n;
yield ++_n;
}
//这是声明了两个迭代器
var aa = xxfn();
var bb = xxfn();
console.log(aa.next())//{done: false,value: 2}
console.log(aa.next())//{done: false,value: 3}
console.log(bb.next())//{done: false,value: 2}//新的调用
console.log(aa.next())//{done: false,value: 4}
</script>
示例3:.next()方法接受参数
传入的参数,其实是把上一个yield语句的返回值给覆盖掉。所以,第一个.next()方法其实是启动器,在它之前没有yield语句,因此给第一个.next()方法传参数是没有意义的。
以下的例子最能体现generator函数用途的例子。
就是通过.next()方法,分阶段的注入数据,让函数分阶段的给出不同的返回值
<script type="text/javascript">
function* xxfn() {
var _n = 1;
var _v = yield _n+22;
console.log('传参数:'+_v)
yield ++_n;
yield ++_n;
}
var _xxfn = xxfn();
/*第一个.next(),他返回的value是23*/
console.log(_xxfn.next())//{value: 23, done: false}
/*第二个.next(),传入的参数,其实就是坝上一个yield语句的返回值覆盖了,
上一个yield语句的值是 var _v = yield _n+22;传入'abc'以后就赋值给了_v.*/
_xxfn.next('abc')//传参数:abc
/*
传入的参数,其实是把上一个yield语句的返回值给覆盖了
但是,他并没有修改之前声明的变量_n的值,_n依然是1,然后二次++n就是2,再一次++n就是3
*/
console.log(_xxfn.next())//{value: 3, done: false}
</script>
示例4:generator函数支持for of 循环
用来迭代generator函数在执行时,生成的那个迭代对象。
<script type="text/javascript">
function* xxfn(){
yield 'a';
yield 'b';
yield 'a';
yield 'd end...';
}
var _xxfn = xxfn();
for(var i of _xxfn){
console.log(i)
}
</script>