迭代器Iterator
迭代器 为各种不同的数据结果提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成便利操作,主要提供for of
工作原理:
创建一个指针对象,指向当前数组的起始位置
第一次调用对象的next方法,会自动指向数据接口的第一个成员
接下来不断用next方法,指针会一直往后移动,直到指向最后一个成员
目前 数组 Set Map 字符串他们的原型上有Symbol.interator,表示可以进行迭代器
只要原型上有Symbol.iterator属性那么就能调用迭代器的next( ) 方法
object原型上是没有Symbol.iterator属性,因为javascript认为object可以直接通过调用key来获取对应的值,不存在顺序调用。
//数组
let arr = [12, 3, 4, 5, 6, 7]
let it = arr[Symbol.iterator]()
it.next() // 12
it.next() // 3
it.next() // 4
...
//Set
let set = new Set([1, 3, 4, 3, 7])
let seti = set[Symbol.iterator]()
seti.next() // 1
seti.next() // 3
seti.next() // 4
let map = new Map([['q', 1]['w', 2]])
let mapi = map[Symbol.iterator]()
mapi.next()
如何给对象添加Symbol.iterator,使他能够使用for of循环
// 需求:现在需要遍历这个对象 必须使用for of遍历,每次返回的是stus的成员
const banjin = {name: 'yiban',stus: ['xiaoming','xiaogang','xiaohong','xiaowang']
}const banjin = {name: 'yiban',stus: ['xiaoming','xiaogang','xiaohong','xiaowang'],[Symbol.iterator]() {let index = 0let that = this // 让this指向当前对象,或者下面使用尖头函数return {next: function () {// return { value: '111', done: false } // 如果这样些会一直输出,应为一直没有结束 if (index < that.stus.length) {index++ // 下标自增,不然index永远为0return { value: that.stus[index], done: false }} else {return { value: undefined, done: true }}}}}
}for (let i of banjin) {console.log(i); // 会提示:TypeError:banji is not iterate ,说明班级这个变量它不能迭代
}
生成器函数
生成器是ES6中新增的一种函数控制、使用的方案,它可以让我们更加灵活的控制函数什么时候继续执行、暂停执行
生成器函数也是一个函数,但是和普通的函数有一些区别:
生成器函数需要在function的后面加一个符号:*
生成器函数可以通过yield关键字来控制函数的执行流程
生成器函数的返回值是一个Generator(生成器)
生成器事实上是一种特殊的迭代器
//普通生成器调用
function* foo() {yield console.log("01")yield console.log("02")yield console.log("03")
}
const fooi = foo()
fooi.next() // 01
fooi.next() // 02
fooi.next() // 03
生成器异步调用
//实现一个借接口请求 loading加载 异步请求数组 loading消失 加上上一次的结果作为下次的参数使用function pro1() {console.log('第一次调用loading');
}function pro2() {setTimeout(() => {console.log('第二次调用异步加载数据,加载成功之后在关闭loading');const num = 1000 // 比如这个请求成的结果参数 传到下个请求中proi.next(num)}, 2000);
}// x: 上一个请求获得结果作为参数传入
function pro3(x) {console.log('第三次调用关闭loadin',x); // 1000
}function * pro() {pro1()let x = yield pro2()let y = yield pro3(x)
}
const proi = pro()
proi.next()