1. 发布了一篇新闻
  2. /api/news/id 从数据库中读取新闻数据,响应给客户端
  3. 在处理某个请求之前,可以加上一个中间件

实现代码

  1. index.js

    const express = require("express");
    const app = express();
    app.use(express.static("./public"));
    const router = express.Router();
    
    router.get("/:id", require("./cache")({ ttl: 10 }), (req, res) => {
      console.log(req.originalUrl, "没有使用缓存");
      // 从数据库中取出对应id的新闻数据
      res.send({
        title: "新闻标题" + req.params.id,
        content: "新闻内容" + req.params.id,
      });
    });
    app.use("/api/news", router);
    
    app.listen(9527);
    
  2. cache.js

    const redis = require("redis");
    const client = redis.createClient();
    const { promisify } = require("util");
    
    const getAsync = promisify(client.get).bind(client);
    const setAsync = promisify(client.set).bind(client);
    
    module.exports = function (options = {}) {
      // 缓存的数据是否是 json 格式
      const isJSON = options.isJSON === undefined ? true : options.isJSON;
      const ttl = options.ttl || -1; // 过期时间
    
      return async function (req, res, next) {
        const key = req.originalUrl;
    
        const content = await getAsync(key);
        if (content) {
          // 有缓存
          console.log(key, "使用了缓存");
          const body = isJSON ? JSON.parse(content) : content;
          res.send(body);
        } else {
          // 没有缓存
          // **如何获取后续响应中的响应体**
          // express 写响应体,最终是通过 res.write 函数完成,重写 write、end 函数
          const defaultWrite = res.write.bind(res),
            defaultEnd = res.end.bind(res);
    
          const chunks = [];
          res.write = function (chunk, ...args) {
            chunks.push(chunk);
            defaultWrite(chunk, ...args);
          };
          res.end = function (chunk, ...args) {
            if (chunk) {
              chunks.push(chunk);
            }
    
            const body = chunks.map((c) => c.toString("utf-8")).join();
            if (ttl < 0) {
              setAsync(key, body);
            } else {
              setAsync(key, body, "EX", ttl);
            }
    
            defaultEnd(chunk, ...args);
          };
          next();
        }
      };
    };
    

演示

多次请求,控制台输出

/api/news/1?a=1&b=2 没有使用缓存
/api/news/1?a=1&b=3 没有使用缓存
/api/news/1?a=1&b=3 使用了缓存
/api/news/1?a=1&b=4 没有使用缓存
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 实现代码
  2. 2. 演示