当前位置: 首页 > 文档资料 > 阅读 express 源码 >

四、课后习题

优质
小牛编辑
124浏览
2023-12-01

自己写一个简单的中间件服务吧~

我的理解就是,一个 stacks 数组存放函数,通过递归消耗数组里面的函数。

以下是我给出的答案,代码是基于 TypeScript 的,target 的版本是 es6。中间件传递的时候不要使用箭头函数哦,要不然会丢失 this。看不懂可以看下面 js 的版本。

import * as http from "http";

interface Request extends http.IncomingMessage{
  body?: {
    name?: string
  }
}

class App {
  private stacks: Function[] = [];
  public request: Request;
  public response: any;
  private index : number = 0;

  constructor() {}

  use(fn: (req: Request, res: any) => any) {
    this.stacks.push(fn.bind(this));
  }

  next(err?: Error){
      const index = this.index++;
      if (this.stacks.length <= index) {
        this.index = 0;
        return;
      }else{
        this.stacks[index](this.request, this.response);
      }
  }

  init(){
    this.request.body = {};
  }

  callback(req: http.IncomingMessage, res: http.ServerResponse){
    this.request = req;
    this.response = res;

    this.init();

    this.next();
  }

  start(port: number, fn: Function){
    const serve = http.createServer(this.callback.bind(this));
    return serve.listen(port, fn);
  }
}


let app = new App();

app.use(function(req, res){
  req.body.name = "yugo";
  return this.next();
});

app.use(function(req, res) {
  res.end(req.body.name);
});

app.start(3000, () => {
  console.log("app stared on http://localhost:3000");
});

编译好的 js 文件代码为

"use strict";
exports.__esModule = true;
var http = require("http");
var App = (function () {
    function App() {
        this.stacks = [];
        this.index = 0;
    }
    App.prototype.use = function (fn) {
        this.stacks.push(fn.bind(this));
    };
    App.prototype.next = function (err) {
        var index = this.index++;
        if (this.stacks.length <= index) {
            this.index = 0;
            return;
        }
        else {
            this.stacks[index](this.request, this.response);
        }
    };
    App.prototype.init = function () {
        this.request.body = {};
    };
    App.prototype.callback = function (req, res) {
        this.request = req;
        this.response = res;
        this.init();
        this.next();
    };
    App.prototype.start = function (port, fn) {
        var serve = http.createServer(this.callback.bind(this));
        return serve.listen(port, fn);
    };
    return App;
}());
var app = new App();
app.use(function (req, res) {
    req.body.name = "yugo";
    return this.next();
});
app.use(function (req, res) {
    res.end(req.body.name);
});
app.start(3000, function () {
    console.log("app stared on http://localhost:3000");
});