工作原理
- 创建一个指针对象,指向数据结构的起始位置。
- 第一次调用next方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next方法,指针会一直往后移动,直到指向最后一个成员
- 每调用next方法返回的是一个包含value和done的对象,{value: 当前成员的值,done: 布尔值}
- value表示当前成员的值,done对应的布尔值表示当前的数据的结构是否遍历结束。
- 当遍历结束的时候返回的value值是undefined,done值为true
模拟实现iterator接口
//模拟实现iterator接口
function iteratorUtil(target) {
let index = 0; //用来表示指针其实位置
return { //返回指针对象
next() { //指针对象的next方法
return index < target.length ? {
value: target[index++],
done: false
} : {
value: target[index++],
done: true
};
}
}
}
//生成一个迭代器对象
let arr = [1, 2, 3];
let iteratorObj = iteratorUtil(arr);
console.log(iteratorObj.next().value);
console.log(iteratorObj.next().value);
console.log(iteratorObj.next().value);
console.log(iteratorObj.next().value);
实现Object对象的遍历
let arr = [1, 2, 3, 4];
var obj = { name: 'kobe', age: 40 };
// console.log(obj[Symbol.iterator]); // undefined
// console.log(arr[Symbol.iterator]); // function
function mockIterator() {
let that = this;
let index = 0;
let length = 0;
if (that instanceof Array) {
length = that.length;
return {
next: function() {
return index < length ? { value: that[index++], done: false } : { value: that[index++], done: true }
}
}
} else {
length = Object.keys(that).length
let keys = Object.keys(that);
return {
next: function() {
return index < length ? { value: that[keys[index++]], done: false } : { value: that[keys[index++]], done: true }
}
}
}
}
Array.prototype[Symbol.iterator] = mockIterator;
Object.prototype[Symbol.iterator] = mockIterator;
for (let i of arr) {
console.log(i);
}
for (let i of obj) {
console.log(i);
}
Iterator除了供forof消费,使用的地方还有
- 解构赋值
- 扩展运算符
对数组和 Set 结构进行解构赋值时,会默认调用Symbol.iterator方法
let [x,y] = [1,2];
var str = 'hello';
[...str] // ['h','e','l','l','o']
generator 生成器
//generator 生成器
function* gen() {
yield 1
yield 2
yield 3
}
//
//基于生成器函数执行的返回结果就是一个迭代器
let g = gen()
console.log(g.next()); //{value:1,done:false}
console.log(g.next());
console.log(g.next());
console.log(g.next());
async await原理
//async await原理 就是基于generator实现
//asyncFunc作用就是传入一个generator函数,然后把函数中的内容基于Iterator迭代器的特点一步一步实现
function API(data) {
return new Promise((re, rj) => {
setTimeout(() => {
re(data)
}, 1000)
})
}
function asyncFunc(generator) {
let iterator = generator()
const next = data => {
let {
done,
value
} = iterator.next(data)
if (done) return value
value.then(data => {
next(data)
})
}
next()
}
asyncFunc(function* () {
let data = yield API(10)
data = yield API(data + 10)
console.log(data);
})
完整版
function asyncFunc(gen) {
return new Promise((re, rj) => {
let iterator = gen()
const next = (val) => {
let res = iterator.next(val)
if (res.done) {
return resolve(res.value)
}
Promise.resolve(res.value).then(
(val) => {
next(val)
},
(error) => {
iterator.throw(error)
}
)
}
next(0)
})
}
forof内部实现
function forof(arr, cb) {
let iterator = arr[Symbol.iterator]()
let result = iterator.next()
while (!result.done) {
cb(result.value)
result = iterator.next()
}
}