Koa源码阅读(一)从搭建Web服务器说起

栏目: Node.js · 发布时间: 7年前

内容简介:先复习一下使用原生 Node.js 搭建一个 Web 服务器。可以看到,我们只需要关注相同的逻辑对应到 Koa 上来,代码量差不多。

先复习一下使用原生 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);
}
复制代码

看到这里大概也能猜出来,我们的逻辑(处理请求和响应)都在 this.callback() 里面。这也是后面要讲的重头戏。

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() 传入的中间件 “捏” 成的。也就是说,中间件处于核心位置,根据我们想要的逻辑处理请求和响应。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

马云现象的经济学分析:互联网经济的八个关键命题

马云现象的经济学分析:互联网经济的八个关键命题

胡晓鹏 / 上海社会科学院出版社 / 2016-11-1 / CNY 68.00

互联网经济的产生、发展与扩张,在冲击传统经济理论观点的同时,也彰显了自身理论体系的独特内核,并与那种立足于工业经济时代的经典理论发生显著分野。今天看来,“马云”们的成功是中国经济长期“重制造、轻服务,重产能、轻消费,重国有、轻民营”发展逻辑的结果。但互联网经济的发展却不应仅仅止步于商业技巧的翻新,还需要在理论上进行一番审慎的思考。对此,我们不禁要问:互联网经济驱动交易发生的机理是什么?用户基数和诚......一起来看看 《马云现象的经济学分析:互联网经济的八个关键命题》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具