koa:当创建一个服务时,做了什么

创建一个简单的应用
// 1、实例化app
var Koa = require('koa');
const app = new Koa();
// 2、声明中间件函数
async function responseTime(ctx, next) {
  const start = new Date();
  await next();
  const ms = new Date() - start + 10;
  ctx.set('X-Response-Time', `${ms}ms`);
}

async function responseContent(ctx, next) {
  if ('/' != this.url) return;
  ctx.body = 'Hello World!';
}
// 3、使用中间件
app.use(responseTime);
app.use(responseContent);
// 4、应用监听端口
app.listen(3000);
app对象
const Emitter = require('events');
class Application extends Emitter {
    constructor() {
        super();

        this.proxy = false;
        // 用于存储中间件
        this.middleware = [];
        this.subdomainOffset = 2;
        this.env = process.env.NODE_ENV || 'development';
        // 上下文
        this.context = Object.create(context);
        this.request = Object.create(request);
        this.response = Object.create(response);
     }
  }
app.use()添加中间件时做了什么
  use(fn) {
    // 省略fn判断
    this.middleware.push(fn);
    return this;
  }
app.listen(3000)监听端口
  listen() {
    const server = http.createServer(this.callback());
    return server.listen.apply(server, arguments);
  }

  callback() {
    // 返回一个用于dispatch中间件的函数,默认从index = 0开始
    const fn = compose(this.middleware);

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

    return (req, res) => {
      res.statusCode = 404;
      // 使用请求和响应对象创建上下文对象
      const ctx = this.createContext(req, res);
      onFinished(res, ctx.onerror);
      // 执行中间件函数并响应
      fn(ctx).then(() => respond(ctx)).catch(ctx.onerror);
    };
  }

function compose (middleware) {
  if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')
  for (const fn of middleware) {
    if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')
  }
  // 提供公开api用于调度中间件函数
  return function (context, next) {
    // last called middleware #
    let index = -1
    return dispatch(0)
    function dispatch (i) {
      if (i <= index) return Promise.reject(new Error('next() called multiple times'))
      // 改变变量index
      index = i
      // 取出当前中间件
      let fn = middleware[i]
      if (i === middleware.length) fn = next
      if (!fn) return Promise.resolve()
      try {
        return Promise.resolve(fn(context, function next () {
          //触发下一中间件执行
          return dispatch(i + 1)
        }))
      } catch (err) {
        return Promise.reject(err)
      }
    }
  }
}
  // 创建上下文对象
  createContext(req, res) {
    const context = Object.create(this.context);
    const request = context.request = Object.create(this.request);
    const response = context.response = Object.create(this.response);
    context.app = request.app = response.app = this;
    context.req = request.req = response.req = req;
    context.res = request.res = response.res = res;
    request.ctx = response.ctx = context;
    request.response = response;
    response.request = request;
    context.onerror = context.onerror.bind(context);
    context.originalUrl = request.originalUrl = req.url;
    context.cookies = new Cookies(req, res, {
      keys: this.keys,
      secure: request.secure
    });
    context.accept = request.accept = accepts(req);
    context.state = {};
    return context;
  }

思维导图
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值