zh-rocco / fe-notes

:memo: 前端笔记

Home Page:https://zh-rocco.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

【JS】Generator 生成器

zh-rocco opened this issue · comments

commented

理解

朋友聚会去饭馆,点好菜可以有两种吃法,第一种,等菜上完大家动筷子,第二种,上一道吃一道。如果按第一种吃法,吃饭的程序要等待做饭的程序(饭馆)全部执行完;按第二种吃法,吃饭的程序和做饭的程序就完成了解耦,做饭的做他的,快或者慢,只要上,吃饭的就吃,不依赖一个最终状态。这两种方法不改变菜的品种质量。但流程效益却不同,如果上一道吃一道,吃完的盘子就可以清掉,如果按第一种吃法,上到中间发现桌子不够大,盘子要叠罗汉。而且第一种吃法,喜欢吃某个菜的朋友可以先吃到,不必死等流口水。如果点三道菜,两种吃法或许没太大差异。但是你想像一下,假设点了3000道菜,两种吃法的效率当下立现,如果按第一种吃法,大家都饿死了,即使做好了,桌子(内存)也放不下。

我上面说解耦,并不完全准确,准确得说,吃饭的程序不再依赖于整桌菜,而只依赖于下一道菜,而依赖于前者往往空间和时间效益都低,而依赖于后者较高。

这是 Generator 的实际意义,在值的使用者和值的生产者之间,建立效益更高的依赖,规避效益不高的依赖。

感谢大神 IT浪人 的解释

作用

  • 悬停/挂起 流程

迭代器(iterator + for...of)

ES6 中除了新特性外,还有一个新的规范,那就是关于迭代的规范,他包括两部分分别是 “可迭代规范(iterable protocol)” 和 “迭代器规范(iterator protocol)”。任何实现了前者的对象,都可以进行 for…of 循环。

String, Array, Map, Set 等是原生可迭代对象,因为他们都在原型(prototype)对象中实现了 Symbol.iterator 键对应的方法

for…of 是对象迭代器的遍历,而 for…in 是对象中 可枚举 值的遍历

// 1. 迭代器规范
const iter = {
  counter: 0,
  next(){    // 迭代器是实现了 "next()" 函数的对象
    if(++this.counter < 10){
      return {    // 返回一个含有两个键值对的对象,Object {done => boolean, value => any}
        done: false,
        value: this.counter
      }
    }else{
      this.counter = 0;
      return {    // done = true 时,value非必须
        done: true
      }
    }
  }
};

// 2. 可迭代规范,实现 "Symbol.iterator => func()" 键值对;而 "func()" 返回一个 迭代器对象
const iterObj = {};
for(var i of iterObj){};    // TypeError: iterObj is not iterable
iterObj[Symbol.iterator] = function() {
  return iter;
};
for(var i of iterObj){
  console.log(i);    // 1,2,3,4,5,6,7,8,9
};

参考