中间件编写

本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2019-11-24

书写中间件,一个用于当请求时间过长而进行提醒的中间件,假设有个页面会想数据库发起一系列的请求,所有的响应都在100ms内完成,但是你要确保能够将响应时间大于100ms的请求记录下来。

// timer.js
// 中间件的开发模式之一:接受一个选项,自身再返回一个中间件函数,参数为req, res, next

module.exports = function(opts) {
  var time = opts.time || 100;
  return function (req, res, next) {
    var timer = setTimeout(() => {
      console.log('is taking too long!');
    }, time)

    // 重写res.end 猴子补丁
    // 并不能使用res.end直接响应 这不是中间件应该做的事情 应该将响应交给业务逻辑。
    // 这里只是重写,当业务逻辑中调用的时候,就是调用这个重写了的函数
    // 我们首先保存了原始的引用,在重写的方法重新调用,并做了额外的事情,清除定时器

    var end = res.end;
    res.end = function(chunk, encoding) {
      res.end = end;
      res.end(chunk, encoding);
      // 当响应的时间小于设置的时间时,上面的setTimeout还没有被执行就被清除了,就不会打印提示。
      // 当响应的时间超过设置的时间时,timer已经被执行,照样需要清楚
      clearTimeout(timer)
    }

    next();
  }
}


// index.js
var connect = require('connect');
var timer = require('./timer');
var server = connect();

server.use(timer({time: 500}));

server.use((req, res, next) => {
  if ('/a' == req.url) {
    // 模拟快速响应
    res.writeHead(200);
    res.end('Fast');
  } else if ('/b' == req.url) {
    // 模拟慢速响应
    setTimeout(() => {
      res.writeHead(200);
      res.end('Slow');
    }, 600)
  }
})

server.listen(3000);

示例2: 实现body-parser

// my-body-parser.js
const queryString = require('querystring');

module.exports = function (req, res, next) {
  var str = '';
  req.on('data', function (data) {
    str += data;
  });

  req.on('end', function () {
    // 中间件的实现,在这里定义了req.body 下面就能使用
    req.body = queryString.parse(str);
    next(); // 调用next 将处理向下传递
  })
}

// index.js
const express = require('express');
const myBodyParser = require('./my-body-parser');
var server = express();

server.listen(8081);

server.use(myBodyParser)

server.use('/', function (req, res) {
  console.log(req.body);
})