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 的异步代码的编写。