1. 关于迭代器的扩展
Iterator 是 ES6 引入的一种新的遍历机制
迭代机制
-
通过 Symbol.iterator 创建一个迭代器,指向当前数据结构的起始位置
-
随后通过 next 方法进行向下迭代指向下一个位置, next 方法会返回当前位置的对象,对象包含了 value 和 done 两个属性, value 是当前属性的值, done 用于判断是否遍历结束
-
当 done 为 true 时则遍历结束
let iterator = arr[Symbol.iterator](arr); //数组迭代器
iterator.next(); //{value:1,done:false}
iterator.next(); //{value:2,done:false}
iterator.next(); //{value:undefined,done:true}
自己手写一个迭代器
//创建迭代器
function createIterator(item) {
let i = 0;
return {
next() {
let done = i >= item.length;
let value = !done ? item[i++] : undefined;
return {
value,
done,
};
},
};
}
let arr = [22, 33, 44, 55];
let it = createIterator(arr);
console.log(it.next());//{value:22,done:false}
console.log(it.next());//{value:33,done:false}
console.log(it.next());//{value:44,done:false}
console.log(it.next());//{value:55,done:false}
console.log(it.next());//{value:undefined,done:true}
2. 生成器 generator
形式
function* gen() {
yield 1;
yield 2;
yield 3;
}
通过生成器返回的是一个迭代器函数
let g = gen(); //这是一个迭代器
console.log(g.next()); //{value: 1, done: false}
console.log(g.next()); //{value: 2, done: false}
console.log(g.next()); //{value: 3, done: false}
console.log(g.next()); //{value: undefiend, done: true}javascript
3. 生成器 generator 的应用
- async/await 底层实现的机制就是基于生成器实现的
function API(num) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(num);
}, 1000);
});
}
//方案一:基于promise中的then处理
API(10)
.then((data) => {
return data + 10;
})
.then((data) => {
console.log(data); //20
});
//方案二:基于async/await处理
async function func() {
let data = await API(10);
data = await API(data + 10);
console.log(data);
}
func();
//方案三
// 传递给我一个Generator函数,我可以把函数中的内容基于Iterator迭代器的特点一步步的执行
function asyncFunc(generator) {
//创建一个迭代器函数,里面有方法next
let iterator = generator();
//创建next函数
const next = (data) => {
let { value, done } = iterator.next(data);
if (done) return data;
value.then((data) => {
next(data);
});
};
next();
}
asyncFunc(function* () {
let data = yield API(100); //{value:API(100),done:false}
data = yield API(data + 10); //{value:API(data + 10),done:false}
console.log(data); //{value:undefined,done:true}
});