如何使用generator
generator其实本身就是一个迭代器iterator
什么是迭代器?
参考https://blog.csdn.net/qq_18433441/article/details/78223502
上面文章中讲解了Java的迭代器:
集合类Collection实现了接口Iterator
所以任何集合类都有一个iterator实例
Iterator iterList= list.iterator();//List接口实现了`Iterable接口
通过
while (iterList.hasNext()){
String str = iterList.next();
}
来遍历迭代器获取元素
那么回到Javascript
ES6才出现generator这么一个对象,
声明generator需要在function后面加上星号*,在函数体中使用”yield”关键字就能将当前函数变成一个地地道道generator函数。
老规矩,先贴代码
function* fn(){
let a=1;
yield a;
a++;
yield a;
a++;
return a
}
let t = fn();
console.log(t); //fn {<suspended>}
let res = t.next();
console.log(res) //{value: 1, done: false}
res = t.next();
console.log(res) //{value: 2, done: false}
res = t.next();
console.log(res) //{value: 3, done: true}
使用步骤如下:
1.定义一个函数(记得加*)并在函数体内部使用yield关键字
function* fn(){
let a=1;
yield a;
a++;
yield a;
}
2.在外面将改函数实例化,并赋值给一个变量。
let t = fn();
3.然后t就是一个迭代器了,通过next()方法获取包含变量值的对象(学术名叫做IteratorResult )。
每次使用t.next()都会获取一个IteratorResult对象,这个是yield的返回值(上面例子中的a),yield等同于return!记住这句话。只不过是带阻塞功能且会把返回值封装成一个IteratorResult对象(下面说的res)。
4.如果我们保存返回值
var res = t.next()
那么res就是该对象,包含两个属性——{ value: xxx , done: true/false}
value是yield关键字后面的对象值(上面说的a);done是用来判断是否通关完所有的yield了(也就是运行途中再也没有遇到yield关键字)
但是,通过所有yield之后再次调用t.next()会遇到如下两种情况:
一:遇到return,那么t.next()的值就等于{ value: (return的值),done:true }
二:没有return了,那么t.next()的值就等于{ value: undefined , done:true}
yield的阻塞原理
上面留下了一个坑,就是——yield是怎么阻塞的?实在yield这行代码之前阻塞住还是之后阻塞住?
解答:这个问题不是所有人都会跟你讲的,我也是自己研究的,首先抛出结论——yield之后
继续只用这段代码
function* fn(){
let a=1;
yield a;
a++;
yield a;
a++;
return a
}
如果是在yield之前堵塞住,那么调用fn()的时候,a就应该被赋值为1了,但是实际上是undefined。
当res = fn()且res.next()通过第一个yield之后。
a才被赋值为1,但是如果是每通过yield就会把下一次yield之前的代码全部执行完毕的话,那么a++也会被执行,此时a=2而不是等于1了。
所以得出结论:
第一次运行fn(),一句代码都不会执行;当执行next(),则会一路畅行直到碰到一个yield,然后会在执行完yield这行代码之后阻塞住。
通过最后一个yield之后代码不会直接执行完毕,否则上面说的return就直接和最后一次yield返回值冲突了(先返回yield的值,然后顺序执行到return又把之前的值覆盖),这是矛盾的,所以通过最后一个yield之后代码仍然阻塞。
然后最后再执行一次next(),代码就会继续往下执行直到碰到一个return,代码执行完毕返回{value:3,done:true}(或者没有遇到return执行完毕返回{value:undefined,done:true})
如果你想更详细地了解yield,我推荐这位博主的文章
深入理解js的yeild
欢迎指错,转载请加上原文链接:
https://blog.csdn.net/weixin_51116314/article/details/114672960