最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

Node.js中间件包装

IT培训 admin 9浏览 0评论

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中间件包装

我正在尝试编写自己的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();
        });
});
...

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论