/**
* Iterator 接口是一种数据遍历的协议
* 只要调用遍历器对象的next方法,就会得到一个对象
* 表示当前遍历指针所在的那个位置的信息。
* next方法返回的对象的结构是{value, done},其中value表示当前的数据的值
* done是一个布尔值,表示遍历是否结束
*/
let idMaker = function () {
let index = 0;
return {
next() {
return { value: index++, done: false }
}
}
}
const it = idMaker()
console.log(it.next().value) // 0
console.log(it.next().value) // 1
console.log(it.next().value) // 2
/**
* 上面代码中 it 就是一个遍历器(iterator)。每次调用 it.next() 方法就会返回
* 一个对象,表示当前遍历位置的信息
*
* 但是这里其实是有些问题的,首先 it.next() 方法必须是同步的,只要调用就必须立刻返回值
* 也就是说,一旦执行 it.next() 方法,就必须同步得到value 和 done 这两个属性
* 乍一看好像没什么问题,但是如果是异步操作就有问题了
* 例如:
* */
let idMaker2 = function () {
let index = 0
return {
next: function () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ value: index++, done: false })
}, 1000)
})
}
}
}
/**
* 这样的话,next()返回的就是个promise对象,这样的话是不符合Iterator协议
*
* 目前解决办法是,将异步操作封装成Thunk函数或者Promise对象
* 也就是说next()返回的 value 属性是一个Thunk函数或者Promise对象
* 等待返回真正的值,而done属性还是同步产生
* 例如:
*/
let idMaker3 = function () {
let index = 0
return {
next: function () {
return {
value: new Promise((resolve, reject) => {
setTimeout(() => {
resolve(index++)
}, 1000)
}),
done: false
}
}
}
}
const it2 = idMaker3()
it2.next().value.then(res => { console.log(res) }) //
it2.next().value.then(res => { console.log(res) }) //
it2.next().value.then(res => { console.log(res) }) //
/**
* 但其实就算这样写 看起来也怪怪的
* 现在引入了 异步遍历接口 asyncIterator
*/
console