迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署迭代器接口,就可以完成遍历操作。
ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费
原生具备Iterator接口的数据有:Array,Arguments,Set,Map,String,TypedArray,NodeList
工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next方法,指针一直往后移,直到指向最后一个成员
- 每调用next方法返回一个包含value和done属性的对象
应用--自定义遍历数据
类似上面的情况,想要遍历对象里面的数组,直接在obj上面遍历时,是会报错的,这个时候就需要自定义遍历:
let obj={ name:'张三', hobby:['足球','羽毛球','游泳','游戏'], [Symbol.iterator](){ let index = 0; return{ next:()=>{ if(index < this.hobby.length){ const result = {value:this.hobby[index],done:false}; index++; return result; }else{ return {value:undefined,done:true} } } } } } for(let v of obj){ console.log(v) }
生成器
生成器是一个特殊的函数,是异步编程的一种解决方式。
next()方法的返回结果
生成器函数参数
在使用next传参时,第n个next的参数将作为第n-1个yield的整体返回结果。
生成器实例
例如,我们想要实现一个1s后打印111,然后过2s后再打印222,再然后3s后打印333的效果,如果使用定时器,可以写成下面这样
这个时候就已经形成了回调地狱,如果还要继续添加的话,嵌套更深,为了解决这种异步的回调,就可以使用生成器:
function one(){ setTimeout(()=>{ console.log(111); iterator.next(); },1000) } function two(){ setTimeout(()=>{ console.log(222); iterator.next(); },2000) } function three(){ setTimeout(()=>{ console.log(333); iterator.next(); },3000) } function * gen(){ yield one(); yield two(); yield three(); } let iterator = gen(); iterator.next();
在实际项目中,经常一个接口的请求需求依赖于另一个接口请求的返回,常规的的做法有回调、promise等方法,除此之外,用生成器也可以实现: