【问题标题】:Express middleware - add promise rejection handlersExpress 中间件 - 添加承诺拒绝处理程序
【发布时间】:2018-03-21 19:27:09
【问题描述】:

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

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 做到这一点?

【问题讨论】:

  • 我想我们可以切换到 Koa,这可能会解决它。但是简单地使用 async/await 可能不会解决它,或者会吗?
  • 做我在问题中寻找的东西并不安全。如果所有中间件都只在 Promise 解析后调用,会更安全。
  • 这最终对我有用:medium.com/@the1mills/…

标签: node.js express express-4


【解决方案1】:

使用express promise router

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:There's no need to be afraid of async/await on performance grounds. 与带有 promise 的常规函数​​没有明显区别。

【讨论】:

  • Promise 的性能明显低于普通回调。但是你可能是对的,async/await 的性能并不比 promise 差。
  • 没错;回调肯定更快,但如果你已经在使用 Promise,async/await 没有额外的惩罚。
  • 接受了答案,尽管顺便说一句,我确实怀疑使用生成器确实会增加内存需求,而不仅仅是承诺,必须更多地研究它
  • 你可能会喜欢这个解决方案 lulz medium.com/@the1mills/…
【解决方案2】:

你可以尝试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 函数返回或抛出时,通过 express 传递给 asyncback 的 next 回调会被自动调用。

【讨论】:

    【解决方案3】:

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

    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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多