Koa笔记

作者: HIKALU | 来源:发表于2018-12-09 23:22 被阅读0次

先复习一下使用原生 Node.js 搭建一个 Web 服务器

var http = require('http');
var server = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'})
  res.end('Hello world\n')
})
server.listen(3000)

可以看到,我们只需要关注 http.createServer() 传入的回调函数和 server.listen() 传入的参数即可。一般来讲, server.listen() 传入 Web 服务器监听的端口号,而 http.createServer()传入的回调函数则负责处理 HTTP 请求并给出响应。
相同的逻辑对应到 Koa 上来,代码量差不多。

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

app.use(ctx => {
  ctx.body = 'Hello world'
})

app.listen(3000)

仔细观察我们发现,server.listen 对应于app.listen,而 http.createServer() 传入的回调函数在 Koa 里则是利用 app.use() 传入的。实际上,处理请求和响应的操作就是由 app.use() 传入的函数完成的。
基于这个思路,我们可以开始分析 Koa 源码中涉及到上面描述的部分。

源码文件

Koa 的源码只有四个文件。其中,负责对外暴露方法的是 application.jscontext.js 封装了请求和响应作为上下文 ctx,而 request.js(请求)和 response.js(响应)则为 context.js提供支持。
核心文件是 application.js,主要是两个方法

1.app.listen() - 监听端口

封装并不复杂,仅仅是将原生 Node.js 启动 Web 服务器的操作放在了一个函数里。

listen(...args) {
  const server = http.createServer(this.callback());
  return server.listen(...args);
}

2. app.use() - 添加中间件

use(fn) {
  // ...
  this.middleware.push(fn);
  // ...
}

实际上就是将传入的中间件函数添加到 this.middleware 中。最终,就是这些中间件函数,构成了处理请求和响应的绝大多数逻辑。

谁来处理中间件

文件开始的时候,我们已经得到一个思路,http.createServer()传入的回调函数负责处理每个 HTTP 请求并给出响应,而现在我们发现传入的是 this.callback() 的返回值,我们来看看它的代码。

callback() {
  const fn = compose(this.middleware);

  // ...

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

  return handleRequest;
}

返回的 handleRequest 局部变量就是我们一直提到的那个回调函数,它与原生 Node.js 搭建的服务器一样,接收请求(req)和响应(res)两个参数。每次请求到来时,这个函数都会被调用,它完成两个工作:

  • 创建一个上下文 ctx,封装了本次的请求和响应
  • 将上下文 ctx 和函数 fn 交由 this.handleRequest() 处理
    对了,这个函数的第一行我们没有介绍,它用到了app.use()传进来的中间件 this.middleware
    const fn = compose(this.middleware);
    中间件机制是 Koa 设计中非常巧妙的一部分,利用中间件我们可以为 Web 服务器提供各种各样的功能。鉴于篇幅,我们只介绍如何把传入的多个中间件变成我们想要的回调函数。
    这里用到的是 koa-compose 这个 NPM 包,它把传入的多个中间件 "捏" 成一个回调函数fn,由它对上下文ctx进行处理,当然也就是 HTTP 请求和响应。

处理请求和响应

上节提到,上下文 ctx和函数 fn 交给了 this.handleRequest() 处理,它进行了以下几项工作:

  • ctx 中将响应默认置为404
  • 定义错误处理函数 onerror,具体会由 ctx.onerror() 执行
  • 定义响应处理函数handleResponse,具体会由 this.respond() 执行
  • 调用中间件 “捏” 成的单个回调函数fn 处理上下文 ctx,其返回一个 Promise 对象,在其then中发出响应(调用 handleResponse),若出错则处理错误(调用 onerror

总结

总的来说,可以将由 Koa 搭建的 Web 服务器的工作原理分为两个过程:
1. 启动服务器
利用 this.callback() 将中间件 “捏” 成一个回调函数传给 http.createServer,同时实例化了一个 Server 对象,调用其 listen方法启动服务器。
2. 处理请求并响应
this.callback() 返回的是一个回调函数,每个新的请求到来,Server 就会调用它并传入请求和响应两个参数。它会创建包含 req 和 res 的上下文 ctx,并调用回调函数 fn 处理 ctx,继而发出响应或错误。而 fn 是由我们调用app.use()传入的中间件 “捏” 成的。也就是说,中间件处于核心位置,根据我们想要的逻辑处理请求和响应。

相关文章

  • koa2学习

    搭建博客 koa2笔记阮一峰koa2 多项目目录结构

  • Koa学习资料

    Koa2进阶学习笔记下一代web框架Koajs的在线课程Koa实战深入浅出 Koa Koajs 中文文档和资料

  • nodejs 学习笔记(1)koa2 koa-generator

    koa2是nondejs的开发框架,最近学习nodejs,这里记记笔记 首先安装好nodejs 安装koa2,全局...

  • KOA笔记

    封装了http,特点是中间件和错误处理 用法 中间件的特点是洋葱模型(为保运行结果在预期内,尽量使用async函数...

  • Koa笔记

    先复习一下使用原生 Node.js 搭建一个 Web 服务器 可以看到,我们只需要关注 http.createSe...

  • Koa自学笔记

    Koa2自学笔记 对应的代码示例:https://codesandbox.io/s/reverent-worker...

  • koa2 用到的中间件

    koa-router //koa路由 koa-bodyparser //post 获取值 koa-stat...

  • koa-router处理URL

    koa-router处理URL koa-router使用的结构const Koa = require('koa')...

  • Koa学习笔记

    中间件 Koa 的最大特色,也是最重要的一个设计,就是中间件(middleware) 中间件的概念 代码中的log...

  • koa学习笔记

    一、中间件1、中间件的执行流程 以上是koa1的写法,koa2的写法有些不同,function * 写成 asyn...

网友评论

      本文标题:Koa笔记

      本文链接:https://www.haomeiwen.com/subject/opdlhqtx.html