飞雪连天射白鹿,笑书神侠倚碧鸳

0%

迭代器Iterator与生成器Generator

迭代器是对象
生成器是返回迭代器的函数
够直接吧

迭代器是什么

迭代器是包含next方法的对象

iterable(可迭代对象):被外界访问的内部元素的数据结构,实现了 Symbol.iterator 方法
iterator(迭代器):遍历数据结构元素的指针

实现一个迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 自定义迭代,数组倒序
const myArr = [1,2,3];
myArr[Symbol.iterator]= function(){
let index = this.length;
return {
next:()=>{
if(index>0){
index--;
return {value:this[index],done:false};
}else{
return {done:true}
}
}
}
}
// [...myArr]; // [3, 2, 1]
// Array.from(myArr); // [3, 2, 1]

myArr有符合标准的 Symbol.iterator 接口,那就是 可迭代的(Iterator) ,调用这个接口返回的对象就是一个 迭代器

关闭迭代器

1、当next()方法返回done:true时,正常执行结束关闭
2、调用符合规范的return()方法关闭

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function myIterable(){
let done = false;
const iterable ={
[Symbol.iterator](){
return this;
},
next(){
return {done:false,value:'- -'}
},
return(){
console.log('~~');
return{done:false,value:undefined}
}
}
return iterable;
}
for (const value of myIterable()) {
console.log(value);
break;
}

生成器Generator

生成器是返回迭代器的函数
Generator既是迭代器也是可迭代对象, 有next()和Symbol.iterator

使用生成器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const getIterator = function *() {
console.log("第1次")
yield "A";
console.log("第2次")
yield "B";
console.log("第3次")
yield "C";
}
const iterator = getIterator();
// 每次调用next会在yield处返回结果并暂停
console.log(iterator.next());
// 传参会替换上一次yield的返回值
console.log(iterator.next(1));

const getIterator2 = function *(array) {
for(let i = 0 ;i < array.length; i++){
yield array[i];
}
}

题目 - 3个苹果,2个香蕉,发完了苹果才能发香蕉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 生成器委托
getAppleIterator = function*() {
yield "a1"
yield "a2"
yield "a3"
}
getBananaIterator = function*(){
yield "b1"
yield "b2"
}
getFruitIterator = function*(){
yield *getAppleIterator();
yield *getBananaIterator();
}
fruit = getFruitIterator();
console.log(fruit.next());

写到这里,想起以前看《你不知道的js》中有generator的概念,遂又去翻了翻

生成器里写业务,任务工具执行,不关心next()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 执行callback的里所有内容直到done:true
let run = function(requestIteratorCreator){
task = requestIteratorCreator();
let result = task.next(); // 先执行
doTask = function(){
if(!result.done){
result = task.next(result.value);
doTask()
}
}
doTask() // 看看是否继续执行
}
let requestIteratorCreator = function*(){
const result = yield 2;
yield result
}
run(requestIteratorCreator)
听说,打赏我的人最后都找到了真爱
↘ 此处应有打赏 ↙
// 用户脚本