09-Koa2实现原理

nobility 发布于 2025-12-13 02-Koa2 289 次阅读


Koa2 实现原理

在 Koa 对象中存储只存储中间对应的方法,使用 use() 方法向队列中添加中间件对象

next 方法是一个有名的立即执行函数,当第一次匹配时会立即执行,使用函数对象的 bind() 方法进行参数绑定,并将包装后的 ctx 参数和该函数传递给用户中间件的方法为参数,若用户调用 next 方法时会调用我们定义好的 next 方法执行下一个中间件方法

将中间件函数的执行结果使用 promise 包装,兼容非 async 函数的中间件

const http = require("http");

/**
 * 将请求对象和响应对象包装成ctx对象
 * @param {Request} req 请求对象
 * @param {Response} res 响应对象
 */
function extendsMethod(req, res) {
  return {
    req,
    res
  };
}
class Koa {
  constructor() {
    this.middlewares = [];  //用于存放中间件方法
  }
  use(...args) {
    this.middlewares.push(...args); //添加到中间件队列
    return this; //链式调用
  }
  listen(...args) {
    const server = http.createServer((req, res) => {
      const ctx = extendsMethod(req, res);  //包装成ctx对象
      const middlewares = this.middlewares; //暂存中间件队列
      //由于中间件队列是地址引用,所以不能使用出队方式,否则下次访问时就没了
      (function next(i) {
        const middleware = middlewares[i];  //取出第i个中间件
        if (!middleware) return;  //若取出的是null,说明后面已经没有中间件了,所以什么也不用做
        try {
          return Promise.resolve(middleware(ctx, next.bind(null, i + 1)));
          //兼容非async函数,包装成promise
          //next.bind(null, i + 1)返回一个参数为i + 1的next函数,用于递归向下调用
        } catch (error) {
          return Promise.reject(error);
        }
      })(0); //立即执行
    });

    server.listen(...args);
  }
}
module.exports = Koa;
加油啊!即便没有转生到异世界,也要拿出真本事!!!\(`Δ’)/
最后更新于 2025-12-13