前言
众所周知, express不像是koa, 不是洋葱皮结构的,所以如果你想在每个handle处理请求的函数结尾处进行一些操作, 你必须得在每个handle里都写,比如有时候你的有些接口会根据请求返回多一部分属性, 或者少一部分属性, 或者是res.json还是res.render, 或者你想统一处理返回数据的格式。这些还都是和req res里的一些东西相关联的, 你只能写一个函数来统一处理, 这就少不了一些if判断了。
nest.js就有一个interceptor的东西, 这里我们就简单实现一下, 看看rxjs如何解决这个问题
import express, {Request, Response, NextFunction, RequestHandler} from "express"
import {Observable} from "rxjs";
import {map, tap} from "rxjs/operators";
const app = express();
/* -------------------------------- 我们需要关心, 写的部分start ----------------------------------------- */
// 路由
app.get("/", wraper(_handle))
// 平时写得最多的处理函数
async function _handle(req: Request, res: Response, next: NextFunction) {
return "hello aop";
}
// aop函数, 在这里我们可以在请求前和请求后统一处理一些东西
function aop(ctx: {req: Request, res: Response}, next: {handle: () => Observable<any>}): Observable<any> {
/*
do something with req/res
*/
const time = Date.now();
return next.handle().pipe(
// 统一返回格式
map(item => {
return {
msg: "ok",
data: item,
statusCode: 1,
}
}),
// 请求耗时记录
tap(() => console.log(`req ${ctx.req.originalUrl} takes ` + (Date.now() - time) + "ms"))
)
}
/* -------------------------------- 我们需要关心, 写的部分end ----------------------------------------- */
/* -------------------------------- 功能部分,只用写一次就行了start ------------------------------------ */
/**
* 包裹函数, 将处理函数包裹在Observable里
* @param handle 接收我们的处理函数为参数
* @returns RequestHandler
*/
function wraper(handle: RequestHandler): RequestHandler {
return (req: Request, res: Response, next: NextFunction) => {
const contextHandle = {
handle: function(): Observable<any> {
return new Observable(subscrib => {
handle(req, res, next).then(
_res => {
subscrib.next(_res);
subscrib.complete()
}
)
})
}
}
aop({req, res}, contextHandle).subscribe({
next(data) {
console.log('got value ' + JSON.stringify(data));
res.json(data);
},
error(err) { console.error('something wrong occurred: ' + err); },
complete() { console.log('done'); }
});
}
}
/* -------------------------------- 功能部分,只用写一次就行了end ------------------------------------ */
app.listen(7894, ()=>console.log("app launch"))
具体是怎么回事, 大家就看代码吧
网友评论