2

我有以下简化的中间件功能:

router.put('/', function (req, res, next) {

  const data = req.body;
  const q = req.parsedFilterParam;
  const opts = req.parsedQueryOpts;

  ResponseCtrl.update(q, data, opts)
  .then(stdPromiseResp(res))
  .catch(next);
});

我想为中间件添加一些捕获错误的能力,只是为了保存一些代码,如下所示:

router.put('/', function (req, res, next) {

  const data = req.body;
  const q = req.parsedFilterParam;
  const opts = req.parsedQueryOpts;

  return ResponseCtrl.update(q, data, opts)
  .then(stdPromiseResp(res));

});

所以我们现在在中间件函数中返回承诺,我们可以放弃 catch 块。

所以在内部,它现在可能看起来像这样:

nextMiddlewareFn(req,res,next);

只是想将其更改为:

const v = nextMiddlewareFn(req,res,next);
if(v && typeof v.catch === 'function'){
   v.catch(next);
});

有谁知道如何用 Express 做到这一点?

4

3 回答 3

2

使用express promise 路由器

var router = new ExpressPromiseRouter();

router.get('/foo', function(req, res) {
  return somethingPromisey();
});
// or...
router.get('/bar', async function(req, res) {
  await somethingPromisey();
});

app.use(router);

PS:没有必要害怕async/await基于性能。 与带有承诺的常规功能没有明显区别。

于 2018-03-21T19:58:34.427 回答
1

您可以为此目的尝试asyncback模块:

const asyncback = require('asyncback');

app.get('/users', asyncback(async (req, res) => {
    const users = await User.find({ 'banned': false });
    const offer = await Offers.findOne({ 'active': true });
    res.json({ 'users': users, 'offer': offer });
}));

当 async 函数返回或抛出时,next通过 express 传递给 asyncback 的回调会被自动调用。

于 2018-03-21T22:02:06.190 回答
0

读者请注意,以下内容实际上不起作用:

router.put('/', async function (req, res, next) {

  const data = req.body;
  const q = req.parsedFilterParam;
  const opts = req.parsedQueryOpts;

  await ResponseCtrl.update(q, data, opts)
  .then(stdPromiseResp(res));

});

如果 promise 被拒绝,则围绕每个中间件的 try/catch 不会实际拾取它,如果 promise 被拒绝,它将冒泡到 unhandledRejection 处理程序(如果有)。

我期待一个好的解决方案:

  1. 可以用 TypeScript 输入
  2. 不使用异步/等待。

这是目前最适合我的解决方案:

https://medium.com/@the1mills/hacking-express-to-support-returned-promises-in-middleware-9487251ca124

于 2018-03-21T19:32:27.843 回答