中间件包装"/>
Node.js中间件包装
我正在尝试编写自己的node.js服务器,到目前为止,我有一个问题。
const asyncHandler = (fn) => async (req, res, next) => {
try {
if (!fn) next();
await fn(req, res, next);
} catch (e) {
next(e);
}
}
const errorHandler = (error, req, res, next) => {
if (!error.code) {
error = new InternalServerError(error.message ? error.message : 'Something broke');
}
const errorResponse = new MessageResponse(error.code, error.message);
res.status(errorResponse.code).send(errorResponse.body);
}
这是两个中间件,第一个中间件处理承诺拒绝,第二个中间件是表达错误处理程序。我正在使用这样的第一个]
router.get('/', asyncHandler(async (req, res, next) => {
let tasks = await TaskService.getAllTasks();
tasks = tasks.map(task => {
return task.entitize();
})
}));
因此,我需要将所有路由中间件功能包装到异步处理程序中以处理拒绝。但是,如果我有10000个路由中间件功能怎么办?是否可以编写一些代码以将所有路由中间件功能按DEFAULT包装到此异步处理程序中?我的意思是这样写
router.get('/', async (req, res, next) => {
throw new Error('aaa');
let tasks = await TaskService.getAllTasks();
tasks = tasks.map(task => {
return task.entitize();
})
});
并且此中间件由asyncHandler包装?有人做过吗?我可以使用任何库来实现此目的吗?提前谢谢。
回答如下:您可以包装原始的router.get
函数,并在那里委派原始函数,从而在其中进行异步/错误处理。这样的事情应该起作用:
const router = express.Router();
const _route = router.route.bind(router);
router.route = function(path) {
const route = _route(path);
route['get'] = wrap(route['get']);
return route;
};
function wrap(originRouterMethod) {
return function() {
const originMiddlewares = [...arguments];
const wrappedMiddlewares = originMiddlewares.map(fn => {
if (typeof fn !== `function`) {
return fn;
}
return async function(req, res, next) {
try {
await fn.apply(null, arguments);
} catch (err) {
console.log('Caught error ' + err);
next(err);
}
};
});
originRouterMethod.call(this, wrappedMiddlewares);
};
}
因此,您无需在设置中将asyncHandler
添加到所有路由,只需将它们指定为:
...
router.get('/', async(req, res, next) => {
let tasks = await TaskService.getAllTasks();
tasks = tasks.map(task => {
return task.entitize();
});
});
...
更多推荐
Node.js中间件包装
发布评论