迭代器(iterator),是确使用户可在容器对象(container,例如链表或数组)上遍访的对象,使用该接口无需关心对象的内部实现细节。
在JavaScript中,迭代器也是一个具体的对象,这个对象需要符合迭代器协议(Iterator protocol):实现一个特定的next方法。
next函数实现调用时返回一个固定对象,{value:'value',done:'boolean'},如果迭代器可以产生序列中的下一个值,则done为false,反之done属性值为true,此时value属性值可以省略。具体的class实现原理如下:
// 创建可迭代类对象
class creatIterator {
constructor(obj) {
this.keys = Object.keys(obj);
};
[Symbol.iterator]() {
let index = 0;
return {
next() {
if (index < keys.length) {
return {
done: false,
value: obj[keys[index++]]
}
} else {
return {
done: true,
value: undefined
}
}
}
}
}
}
在创建的实现迭代器的类中,按照迭代器定义规范实现next函数,返回特定的结果。
迭代器运用的场景--for...of,展开语法,yield,解构赋值。
- 创建一些对象时:new Map([Iterable])、new WeakMap([iterable])、new Set([iterable])、new WeakSet([iterable]);
- 一些方法的调用:Promise.all(iterable)、Promise.race(iterable)、Array.from(iterable);
- 在for...of中要求遍历的对象是可迭代的,无法直接遍历对象,可通过将对象处理成可迭代对象,实现for...of遍历操作。构造函数实现方法:
-
// 传入一个对象,返回可迭代对象 function CreatIteratorFn(obj) { this.keys = Object.keys(obj); let index = 0; return { next() { if (index < keys.length) { return { done: false, value: obj[keys[index++]] } } else { return { done: true, value: undefined } } } } } const arr = [1, 2, 3, 4, 5] const obj = { age: 18, name: 'alison' } const demo2 = CreatIteratorFn(obj); console.log('demo2', demo2.next()); //demo2 { done: false, value: 18 }
迭代器的中断----
-
class creatIterator { constructor(obj) { this.obj = obj; this.keys = Object.keys(obj); }; [Symbol.iterator]() { let index = 0; return { next: () => { if (index < this.keys.length) { return { done: false, value: this.obj[this.keys[index++]] } } else { return { done: true, value: undefined } } }, return: () => { console.log("迭代器提前终止了~") return { done: true, value: undefined } } } } }
生成器----generator
-
生成器是ES6中新增的一种控制函数、使用的方案,它可以让我们更加灵活的控制函数什么时候执行、暂停执行等。
-
生成器函数与普通函数的写法不同点在于需要在function关键字后面添加一个符号 *。
-
生成器函数可以通过yield控制函数的执行流程。
-
生成器函数返回的是一个生成器对象,对象拥有next方法,通过调用next方法执行函数的代码段。
利用生成器函数模拟服务器请求:
// 模拟请求函数 匹配正确网址
function request(url) {
const urlRule = /^w{3}\.{1}.+\.{1}(com|cn|org){1}\b$/;
return new Promise((resolve, reject) => {
setTimeout(() => {
if (urlRule.test(url)) {
resolve('网址匹配成功,正在解析网络地址')
} else {
reject('输入网址非法,请重新输入');
}
}, 2000)
})
}
// 封装生成器函数,执行异步代码
function* execGen(fn) {
yield request('www.baidu1.com')
yield request('www.baidu2.com')
yield request('wwwbaidu3.com')
}
const gen = execGen();
console.log(gen.next().value.then(res => {
console.log(res);
}).catch(err => console.log(err)));
console.log(gen.next().value.then(res => {
console.log(res);
}).catch(err => console.log(err)));
console.log(gen.next().value.then(res => {
console.log(res);
}).catch(err => console.log(err)));
生成器实际上是一种特殊的迭代器,通过将函数编写为生成器函数可以实现分段调用,yield关键字作为函数分段执行的关键字,同时生成器函数也可以调用return方法结束函数的执行。throw关键字在生成器函数中也同样适用,可以捕获生成器函数内部的异常。