【问题标题】:Return inside express router middleware返回内部快速路由器中间件
【发布时间】:2018-01-06 20:39:22
【问题描述】:

如果我有一个简单的快速路由器,它什么都不返回(未定义),有没有办法从中恢复,或者请求会挂起直到超时?

例如,如果我有这个代码:

const express = require('express');
const app = express();
const router = express.Router();

router.use((req, res, next) => {
    console.log('stuck');
    return;
});

app.use(router);

app.get('/', (req, res) => res.send('Hello World!'));

app.listen(3000, () => console.log('Example app listening on port 3000!'));

应用程序在打印stuck 后挂起。如果我返回next(),请求会继续,但我想看看是否有办法从空的返回语句中恢复,而无需在某些时候调用next()

提前致谢!

【问题讨论】:

  • 你回来之前为什么不打电话给next()
  • 是的,在这个任意的例子中我完全可以。我将编辑问题以更清楚地表明我想在不调用 next 的情况下恢复。在我使用它的实际环境中,无法强制调用 next,但我仍想恢复
  • 如果没有next(),您将无法恢复,除非您要禁止处理程序中的任何异步代码。如果处理程序中有异步代码,那么它将在异步代码完成之前返回。这就是为什么必须使用next()

标签: javascript node.js express return


【解决方案1】:

由于您不想调用next(),您可以包装处理程序。

类似这样的:

const withReturnNext = (func) => (req, res, next) => {
    func(req, res);
    next();
}
app.use(withReturnNext((req, res) => res.set('x-headername', 'value'));

但是,这是不可取的,因为任何异步代码都会在异步操作完成之前返回,导致 next() 在它应该被调用之前被调用。

【讨论】:

  • 如果处理程序使用任何异步代码,这将不起作用,因为它将在异步代码完成并执行其操作之前调用next()
  • 是的,我在底部的免责声明中提到了这一点
  • 所以您发布了“不可取”的答案?
  • 好吧,这就是 OP 要求的。
  • 但是,如果您想在响应中快速添加标头,仍然可以使用此代码。在这种情况下它会很好地工作,你只需要小心你没有使用任何异步代码
【解决方案2】:

您必须使用next() 来继续中间件链。如果你从函数返回,你只是终止链,如果后续函数负责响应,你将不会得到它。如果你想终止(例如因为出现问题)但仍然完成请求,你可以使用类似的东西:

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something went wrong')
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 1970-01-01
    • 2017-02-26
    • 2015-01-22
    相关资源
    最近更新 更多