12 Generator_02

61 阅读2分钟
│   ├── Generator 函数的`this`
│   │     └─ Generator 函数总是返回一个遍历器,ES6 规定这个遍历器是 Generator 函数的实例,也继承了 Generator 函数的`prototype`对象上的方法。
│   │     └─ Generator 函数也不能跟`new`命令一起用,会报错。
│   │     └─ 首先,生成一个空对象,使用`call`方法绑定 Generator 函数内部的`this`。这样,构造函数调用以后,这个空对象就是 Generator 函数的实例对象了。
│   ├── 含义
│   │     └─ Generator 与状态机
│   │     └─ Generator 与协程
│   │         └─ 协程(coroutine)是一种程序运行的方式,可以理解成“协作的线程”或“协作的函数”。协程既可以用单线程实现,也可以用多线程实现。前者是一种特殊的子例程,后者是一种特殊的线程。
│   │         └─ 从实现上看,在内存中,子例程只使用一个栈(stack),而协程是同时存在多个栈,但只有一个栈是在运行状态,也就是说,协程是以多占用内存为代价,实现多任务的并行。
│   │         └─ Generator 函数是 ES6 对协程的实现,但属于不完全实现。Generator 函数被称为“半协程”(semi-coroutine),意思是只有 Generator 函数的调用者,才能将程序的执行权还给 Generator 函数。如果是完全执行的协程,任何函数都可以让暂停的协程继续执行。如果将 Generator 函数当作协程,完全可以将多个需要互相协作的任务写成 Generator 函数,它们之间使用`yield`表达式交换控制权。
│   │     └─ Generator 与上下文
│   │         └─ 堆栈是“后进先出”的数据结构,最后产生的上下文环境首先执行完成,退出堆栈,然后再执行完成它下层的上下文,直至所有代码执行完成,堆栈清空。
│   │         └─ Generator 函数,它执行产生的上下文环境,一旦遇到`yield`命令,就会暂时退出堆栈,但是并不消失,里面的所有变量和对象会冻结在当前状态。等到对它执行`next`命令时,这个上下文环境又会重新加入调用栈,冻结的变量和对象恢复执行。
│   │         └─ 
│   ├── 应用
│   │     └─ Generator 可以暂停函数执行,返回任意表达式的值
│   │     └─ (1)异步操作的同步化表达
│   │         └─ `yield`表达式,本身是没有值的,总是等于`undefined`。
│   │     └─ (2)控制流管理
│   │     └─ (3)部署 Iterator 接口
│   │         └─ 利用 Generator 函数,可以在任意对象上部署 Iterator 接口。