├── Generator 函数的异步应用
│ ├── 传统方法
│ │ └─ 回调函数 事件监听 发布/订阅 Promise
│ ├── 基本概念
│ │ └─ 异步
│ │ └─ 所谓"异步",简单说就是一个任务不是连续完成的,可以理解成该任务被人为分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段。
│ │ └─ 回调函数
│ │ └─ JavaScript 语言对异步编程的实现,就是回调函数。所谓回调函数,就是把任务的第二段单独写在一个函数里面,等到重新执行这个任务的时候,就直接调用这个函数。回调函数的英语名字`callback`,直译过来就是"重新调用"。
│ │ └─ 为什么 Node 约定,回调函数的第一个参数,必须是错误对象`err` 原因是执行分成两段,第一段执行完以后,任务所在的上下文环境就已经结束了。在这以后抛出的错误,原来的上下文环境已经无法捕捉,只能当作参数,传入第二段。
│ │ └─ Promise
│ │ └─ Promise 的写法只是回调函数的改进,使用`then`方法以后,异步任务的两段执行看得更清楚了,除此以外,并无新意。
│ │ └─ Promise 的最大问题是代码冗余,原来的任务被 Promise 包装了一下,不管什么操作,一眼看去都是一堆`then`,原来的语义变得很不清楚。
│ ├── Generator 函数
│ │ └─ 协程
│ │ └─ - 第一步,协程`A`开始执行。
│ │ └─ - 第二步,协程`A`执行到一半,进入暂停,执行权转移到协程`B`。
│ │ └─ - 第三步,(一段时间后)协程`B`交还执行权。
│ │ └─ - 第四步,协程`A`恢复执行。
│ │ └─ 协程的奥妙就在其中的 `yield`命令。它表示执行到此处,执行权将交给其他协程。也就是说,`yield`命令是异步两个阶段的分界线。
│ │ └─ 协程的 Generator 函数实现
│ │ └─ Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。
│ │ └─ 整个 Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。异步操作需要暂停的地方,都用`yield`语句注明
│ │ └─ `next`方法的作用是分阶段执行`Generator`函数。每次调用`next`方法,会返回一个对象,表示当前阶段的信息(`value`属性和`done`属性)。`value`属性是`yield`语句后面表达式的值,表示当前阶段的值;`done`属性是一个布尔值,表示 Generator 函数是否执行完毕,即是否还有下一个阶段。
│ │ └─ Generator 函数的数据交换和错误处理
│ │ └─ Generator 函数还有两个特性,使它可以作为异步编程的完整解决方案:函数体内外的数据交换和错误处理机制。
│ │ └─ `next`返回值的 value 属性,是 Generator 函数向外输出数据;`next`方法还可以接受参数,向 Generator 函数体内输入数据。
│ │ └─
│ │ └─ 异步任务的封装
│ ├── Thunk 函数
│ │ └─ Thunk 函数是自动执行 Generator 函数的一种方法。
│ │ └─ 参数的求值策略
│ │ └─ 参数的求值策略
│ │ └─
│ │ └─ Thunk 函数的含义
│ │ └─ 编译器的“传名调用”实现,往往是将参数放到一个临时函数之中,再将这个临时函数传入函数体。这个临时函数就叫做 Thunk 函数。
│ │ └─ JavaScript 语言的 Thunk 函数
│ │ └─ JavaScript 语言是传值调用,它的 Thunk 函数含义有所不同。在 JavaScript 语言中,Thunk 函数替换的不是表达式,而是多参数函数,将其替换成一个只接受回调函数作为参数的单参数函数。
│ │ └─ 任何函数,只要参数有回调函数,就能写成 Thunk 函数的形式。
│ │ └─ Thunkify 模块
│ │ └─ Generator 函数的流程管理
│ │ └─ Thunk 函数的自动流程管理
│ │ └─ Thunk 函数真正的威力,在于可以自动执行 Generator 函数。