co 是 koa 中使用到的基础库,用于 Generator
委派执行,并且可以让开发者更方便编写非阻塞的代码。
以下是使用 co
执行的一个例子:
1 | const co = require('co') |
函数在 co
中执行的整体流程图如下
主要的核心部分是在返回的 Promise
实例中,其的执行流程如下:
- 判断传入
co
中的gen
是否为函数,如果是函数,则绑定当前的上下文到gen
中,并传入gen
执行时所需要的参数,代码如下,然后进入 2
1 | if (typeof gen === 'function') gen = gen.apply(ctx, args); |
- 如果函数
gen
不是合法的值,或者其不是Generator function
,在Promise
直接return resolve(gen)
,否则进入步骤 3,代码如下:
if (!gen || typeof gen.next !== 'function') return resolve(gen);
- 执行在
Promise
中定义的私有函数onFulfilled
。
co
中核心部分函数 onFulfilled
的执行流程
- 首先执行
gen.next(res)
(res
在第一次执行时为undefined
),如果执行出错,转入步骤2
,如果成功执行,转入步骤3
; - 直接执行
reject(e)
,并直接返回; - 执行
next(ret)
,转入步骤4
; - 结束
onFulfilled
执行。
onFulfilled
中核心部分是 next(ret)
,其执行流程如下
- 如果在
co
中执行的是Generator
, 并且其已经执行完res.done
为true
,直接将return resolve(res.value)
,否则进入步骤2
; - 通过调用函数
toPromise
,将res.value
转换为Promise
,然后进入步骤3
; - 如果
toPromise
返回的是Promise
,则通过then
方法求解return value.then(onFulfilled, onRejected)
,否则进入步骤4
; toPromise
的返回值是不支持类型,调用onRejected
打印出debug
信息,并继续调用函数next
求解,返回步骤1
继续执行。
在 toPromise
支持了下面几种类型,转换到 Promise
:
- Generator function
- Normal function
- JavaScript object
- JavaScript array
以上便是 co
的整个执行流程,通过把 Generator function
放入 Promise
中执行,进一步简化了 JavaScript 的异步代码的编写。