详解KOA2如何手写中间件(装饰器模式)

2020-06-17 06:53:22易采站长站整理

let [head, tail] = lines.split(`${lineBreak}${lineBreak}`);

// 判断是否是文件,如果是文件则创建文件并写入,如果是普通值则存入 fields 对象中
if (head.includes("filename")) {
// 防止文件内容含有换行而被分割,应重新截取内容并去掉最后的换行
let tail = lines.slice(head.length + 2 * lineBreak.length, -lineBreak.length);

// 创建可写流并指定写入的路径:绝对路径 + 指定文件夹 + 随机文件名,最后写入文件
fs.createWriteStream(path.join(__dirname, options.uploadDir, uuid())).end(tail);
} else {
// 是普通值取出键名
let key = head.match(/name="(w+)"/)[1];

// 将 key 设置给 fields tail 去掉末尾换行后的内容
fields[key] = tail.toString("utf8").slice(0, -lineBreak.length);
}
});

// 将处理好的 fields 对象挂在 ctx.request.fields 上,并完成 Promise
ctx.request.fields = fields;
resolve();
});
});

// 向下执行
await next();
}
}

上面的内容逻辑可以通过代码注释来理解,就是模拟 koa-better-body 的功能逻辑,我们主要的关心点在于中间件实现的方式,上面功能实现的异步操作依然是读取数据,为了等待数据处理结束仍然在 Promise 中执行,并使用 await 等待,Promise 执行成功调用 next 。

koa-views 中间件模拟

Node 模板是我们经常使用的工具用来在服务端帮我们渲染页面,模板的种类繁多,因此出现了 koa-view 中间件,帮我们来兼容这些模板,先安装依赖的模块。


npm install koa koa-views ejs

下面是一个 ejs 的模板文件:

文件:index.ejs


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ejs</title>
</head>
<body>
<%=name%>
<%=age%>

<%if (name=="panda") {%>
panda
<%} else {%>
shen
<%}%>

<%arr.forEach(item => {%>
<li><%=item%></li>
<%})%>
</body>
</html>

koa-views 具体用法如下:

koa-views 的用法


const Koa = require("koa");
const views = require("koa-views");
const path = require("path");

const app = new Koa();

// 使用中间件
app.use(views(path.resolve(__dirname, "views"), {
extension: "ejs"
}));

app.use(async (ctx, next) => {
await ctx.render("index", { name: "panda", age: 20, arr: [1, 2, 3] });