Koa教程

Koa -- 基于 Node.js 平台的下一代 web 开发框架。

Koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。使用 Koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率。Koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。

源码解析(v2.5.2)

源码目录结构

Koa 的源码都在 lib 目录下(不过 koa 框架依赖了很多 node_modules),其目录结构如下:

lib
├── application.js        # 入口文件,也是骨架文件,创建一个服务
├── context.js            # app 的 context 对象, 传入中间件的上下文对象。
├── request.js            # app 的请求对象,包含请求相关的一些属性。
├── response.js           # app 的响应对象,包含响应相关的一些属性

Hello Koa

首先看一下原生 node 和 koa 分别是如何创建一个 server:

/**
 * 原生Node创建server
 */

const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain;charset=utf-8');
  res.end('Hello World\n');
});

server.listen(3000);

/**
 * Koa创建server
 */

const Koa = require('koa');
const app = new Koa();

app.use(async ctx => {
  ctx.body = 'Hello Wolrd';
});

app.listen(3000);

看一下源码中koa究竟都做了什么?

// 1.首先创建了一个Application的类,继承了Emitter类,然后暴露出去。
module.exports = class Application extends Emitter {
  constructor() {
    super();
  }
  // 2.类下面有一个listen方法,创建http服务
  listen(...args) {
    debug('listen');
    const server = http.createServer(this.callback());
    return server.listen(...args);
  }
}

在 Hello Koa 中,引入这个类,然后实例化这个类,在使用下面的 listen 即搭建起了一个简单的 koa 服务。

然后讲一下初始化 koa 的时候,这个类的下面有一个 use 方法,也就是我们添加中间件的方法:

use(fn) {
    
    // 如果 use 里面传的不是方法,直接错误抛出去
    if (typeof fn !== 'function') throw new TypeError('middleware must be a function!');
    
    // 如果是星号函数,用一个库转成 async await 方法(去兼容 koa1 的中间件)
    if (isGeneratorFunction(fn)) {
      // 如果是 generator 函数,用 convert 转成 async 函数,然后执行。也是就是 koa2 能支持 koa1 的中间件。
      deprecate('Support for generators will be removed in v3. ' +
                'See the documentation for examples of how to convert old middleware ' +
                'https://github.com/koajs/koa/blob/master/docs/migration.md');
      fn = convert(fn); // 转 async await 方法
    }
    debug('use %s', fn._name || fn.name || '-');
    this.middleware.push(fn); // koa 把所有的中间件都放在一个数组里面
    return this;
}

如代码所示,koa 把所有的中间件放在一个数组里面,然后 koa2 也是兼容 generato r函数,为了兼容 koa1 的中间件。

callback 方法 Koa 处理请求的方法:

callback() {
    const fn = compose(this.middleware); // 组装中间件

    if (!this.listenerCount('error')) this.on('error', this.onerror);

    const handleRequest = (req, res) => {
      const ctx = this.createContext(req, res);
      return this.handleRequest(ctx, fn);
    };

    return handleRequest;
  }

Koa中间件(middleware)

首先用一段简单的代码了解一下中间件执行顺序:

基础

Why Koa?

  • async/await 写法,让异步更加优雅。(代码是写给人看得,顺便让机器执行而已
  • 良好的抽象,简介的api,简单、吊炸天的中间件机制
  • 强大的社区
上次更新: 2018-7-17 18:00:22