迭代器是对象
生成器是返回迭代器的函数
够直接吧
迭代器是什么
迭代器是包含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有符合标准的 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();
console.log(iterator.next());
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
| 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)
|