1.迭代器是一种特殊的对象,它有一个next()方法;
每次调用都会返回一个结果对象->{done: xxx, value: xxx},它有done和value两个属性。
function createIterator(arr) {
let i = 0
return {
next() {
let done = i >= arr.length
let value = done ? undefined : arr[i++]
return { done, value }
}
}
}
let iterator = createIterator([2,4,6])
console.log(iterator.next()) // {done: false, value: 2}
console.log(iterator.next()) // {done: false, value: 4}
console.log(iterator.next()) // {done: false, value: 6}
console.log(iterator.next()) // {done: true, value: undefined}
2.生成器是一种返回迭代器的函数。
不能用箭头函数来创建生成器。(1.标准规定;2.箭头函数是轻量级应用,类似单线程,不应增加包袱)
function *createGenerator(arr) {
for(let i=0; i<arr.length; i++) {
yield arr[i]
}
}
let generator = createGenerator([2,4,6])
console.log(generator.next()) // {done: false, value: 2}
console.log(generator.next()) // {done: false, value: 4}
console.log(generator.next()) // {done: false, value: 6}
console.log(generator.next()) // {done: true, value: undefined}
3.迭代器的作用: 1.循环内部索引跟踪(迭代器 + for-of循环)
// 不使用迭代器for循环
let arr = [2,4,6]
for(let i of arr) {
console.log(arr[i])
}
// 1
// 2
// 3
let arr = [2,4,6]
let iterator = arr[Symbol.iterator]() // -> 可迭代的对象都具有Symbol.iterator属性
console.log(iterator.next()) // {done: false, value: 2}
console.log(iterator.next()) // {done: false, value: 4}
console.log(iterator.next()) // {done: false, value: 6}
console.log(iterator.next()) // {done: true, value: undefined}
注: 判断是否为可迭代对象** -> Symbol.iterator
function isIterable(obj) {
return typeof obj[Symbol.iterator] === 'function'
}
4.内建迭代器: ES6中为三种集合对象Array,Map和Set内置了三种迭代器。
entries() -> 返回键值对
values() -> 返回集合的值
keys() -> 返回集合的键
let arr = [1,2,3]
for(let i of arr.entries()){
console.log(i)
}
// [0,1]
// [1,2]
// [2,3]
每一个集合类型都有一个默认的迭代器,在for-of中,如果没有显示指定则使用默认的迭代器。
Array和Set集合的默认迭代器是values()方法;Map集合的默认迭代器是entries()方法。
扩展 for-of (只支持Array,String,Map,Set;不支持Object)。
对于数组,for-of只遍历数字类型的索引;for-in遍历所有属性。
->创建可迭代对象
let obj = {
arr: [2,4,6],
*[Symbol.iterator]() {
for(let i of this.arr) {
yield i
}
}
}
for(let i of obj){
console.log(i)
}
// 1
// 2
// 3
5.高级迭代器功能: 1.给迭代器传递参数;2.生成器返回语句;3.委托生成器
// 1.给迭代器传递参数
function *createIterator() {
let first = yield 1
let second = yield first + 2
yield second + 3
}
let itetator = createIterator()
console.log(itetator.next()) // {done: false, value: 1}
console.log(itetator.next(4)) // {done: false, value: 6} -> 为first赋值,返回first+2
console.log(itetator.next(5)) // {done: false, value: 8} -> 为second赋值,返回second+3
console.log(itetator.next()) // {done: true, value: undefined}
// 2.生成器返回语句
function *createIterator() {
yield 1
return 2
yield 3
}
let itetator = createIterator()
console.log(itetator.next()) // {done: false, value: 1}
*!console.log(itetator.next()) // {done: true, value: 2}
console.log(itetator.next()) // {done: true, value: undefined}
// 3.委托生成器 - 合并迭代器
function *createNumIterator() {
yield 1
yield 2
}
function *createColorIterator() {
yield 'red'
yield 'green'
}
function *createIterator() {
yield *createNumIterator()
yield *createColorIterator()
yield true
}
let itetator = createIterator()
console.log(itetator.next()) // {done: false, value: 1}
console.log(itetator.next()) // {done: false, value: 2}
console.log(itetator.next()) // {done: false, value: 'red'}
console.log(itetator.next()) // {done: false, value: 'green'}
console.log(itetator.next()) // {done: false, value: true}
console.log(itetator.next()) // {done: true, value: undefined}
// 4.委托生成器 - 迭代器间传值
function *createNumIterator() {
yield 1
yield 2
return 3
}
function *createRepeatIterator(count) {
for(let i = 0; i < count; i++) {
yield 'repeat,' + i
}
}
function *createIterator() {
let result = yield *createNumIterator()
yield *createRepeatIterator(result)
}
let itetator = createIterator()
console.log(itetator.next()) // {done: false, value: 1}
console.log(itetator.next()) // {done: false, value: 2}
console.log(itetator.next()) // {done: false, value: 'repeat, 0'} 注: 不打印3;需要yield result;return只有在最后一个迭代器中使用才能打印
console.log(itetator.next()) // {done: false, value: 'repeat, 1'}
console.log(itetator.next()) // {done: false, value: 'repeat, 2'}
console.log(itetator.next()) // {done: false, value: undefined}
6.异步任务执行
// 1.向任务执行器传值
function run(fn) {
let task = fn() // 实例化生成器
let result = task.next()
function step() {
if(!result.done) {
result = task.next(result.value)
step()
}
}
step()
}
run(function *(){
let value = yield 1
console.log(value) // 1 --> 先执行yield 1, 通过next(result.value), 将result.value-1传值给let value...
value = yield value + 3
console.log(value) // 4
})
// 2.异步任务执行器
function run(fn) {
let task = fn() // 实例化生成器
let result = task.next()
function step() {
if(!result.done) {
if(typeof result.value === 'function') {
setTimeout(() => {
let data = result.value(1)
result = task.next(data)
step()
}, 1000)
} else {
setTimeout(() => {
result = task.next(result.value)
step()
}, 1000)
}
}
}
step()
}
function fn(val) {
return val * 2
}
run(function *(){
let value = yield fn
console.log(value) // 2 --> 先执行yield fn, 通过next(result.value), 将result.value-1传值给let value...
value = yield value + 3
console.log(value) // 5
})