最近在写RN相关的东西,其中涉及到了redux-saga ,saga的实现原理就是ES6中的Generator函数,而Generator函数又和迭代器有着密不可分的关系。所以本篇博客先学习总结了iterator相关的东西,然后又介绍了Generator相关的内容,最后介绍了使用Generator进行异步编程。本篇博客所涉及的示例使用TypeScript语言编写,当然所涉及的特性是基于ES6规范的,使用TS语言不影响来阐述和总结ES6的相关特性。下篇博客准备系统梳理一下saga相关的内容。
一、迭代器
之前再聊迭代器模式时,使用Swift语言自定义过迭代器,在TS中也有迭代器。此处的迭代器与之前所介绍的迭代器是大同小异的。首先我们先来自定义一个迭代器,然后再看一下ES6中的迭代器的使用方式。
1、自定义迭代器
下方定义了一个迭代器函数,函数说明如下:
该函数接收一个数组类型的参数,我们可以将需要创建迭代器的数组作为参数传进来。
函数内部定义了一个 nextIndex 参数用来记录迭代器的位置。
该函数返回一个迭代器对象,该迭代器对象包含一个key为 next , value为匿名函数的属性。
这个key为 next 的匿名方法的返回值为每次迭代器的返回结果对象,这个结果对象由 两个属性组成,value表示本次迭代器的值,done表示迭代器遍历是否结束。遍历到最后,最终返回的值为 { value: undefine, done: true }, 也就意味着迭代器遍历结束,value是undefined, done为true。
自定义完迭代器后,我们就可以对上述代码进行测试了。
首先创建了一个数组,然后将数组传给 makeIterator 函数。
而 makeIterator 函数会返回一个含有next方法的迭代器对象。
我们将这个迭代器对象命名为 iterator,我们就可以通过 iterator的next方法来依次获取数组中的值了。
我们通过 while 循环来不断的调用 iterator中的next方法,直到next方法返回的对象中的done值为true时,表示遍历结束。
遍历结束后,我们再次调用 next() 方法,得到的是{ value: undefind, done: true } 的对象,表示遍历结束,获取的value值为 undefined。
2、2。ES6中的迭代器类似于Swift语言的特性,ES6规范中我们可以直接通过一些对象获取该对象所对应的迭代器,如下所示:
下方示例中使用的数组和上面使用的list是一个,首先我们通过 list[Symbol.iterator]() 的方式获取了 list对应的迭代器。
(Symbol也是一种数据类型, 该数据类型用来表示独一无二的对象)该迭代器的使用方式和输出结果与上述我们自定义的迭代器的使用方式完全一致, 输出结果与之前的结果也是一致的。
3、使用 for - of 遍历迭代器
上述方式创建的迭代器我们是使用的while循环来进行遍历的,除了while循环,我们还可以通过for-of 进行遍历。
此处的 for - of遍历方式类似于Swift语言中的 for - in循环,可以依次的自动去除迭代器中的值。
下方就是使用for - of 来循环遍历创建的迭代器。
从下方示例中我们不难看出直接输出的是迭代器返回对象的value值。
4、在类中添加迭代器
我们可以在自己的类中添加相关方法,使我们自己的类支持迭代器。下方就创建了一个 RangeIterator 类,该类的作用是可以定义一个范围,构造器可以接受两个值,一个是范围的起始位置另一个是范围的结束点。下方我们为该范围类添加了自定义迭代器,具体说明如下:
在该类中添加了一个名为 next 的箭头函数,在该函数中做的事情与之前我们自定义的next方法差不多,主要是用来获取下一个值然后返回。
然后又实现一个[Symbole.iterator]函数,用来获取迭代器对象。最后我们可看到定义的范围对象可以向迭代器那样使用for-of进行遍历。
5、调用迭代器的场景
迭代器的使用场景还是蛮多的,解构赋值、扩展运算符、Generator函数、yield*, 下方会简单的列举出来。
(1)、对数组或者集合的解构赋值