node.js express: 中间件有取消http响应的方法吗?

node.js express: Is there a way to cancel http response in middleware?

我正在 node.js.

中用 express 写一个超时中间件
app.use((req, res, next) => {
  res.setTimeout(3000, () => {
    console.warn("Timeout - response end with 408")
    res.status(408).json({ "error": "timeout 408" });
    // !!! error will happen with next function when call like `res.send()`:
    // Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
  next()
})

如果有一个端点花费超过 3000 毫秒,我的中间件将响应 408。但是,下一个函数将再次响应。我不想每次都检查 res.headersSent api 是否已发送响应。

有没有更好的方法来处理这个 - 如标题所说 - 取消中间件中的下一个响应?


响应处理程序中您自己的代码仍然是 运行(可能正在等待某些异步操作完成)。无法从该代码外部告诉解释器停止 运行 该代码。 Javascript 没有该功能,除非您将该代码放在 WorkerThread 或单独的进程中(在这种情况下,您可以杀死那个 thread/process)。

如果您只是想在代码最终尝试发送其响应时(在已发送超时响应之后)抑制该警告,您可以这样做:

app.use((req, res, next) => {
  res.setTimeout(3000, () => {
    console.warn("Timeout - response end with 408")
    res.status(408).json({ "error": "timeout 408" });

    // to avoid warnings after a timeout sent, 
    // replace the send functions with no-ops
    // for the rest of this particular response object's lifetime
    res.json = res.send = res.sendFile = res.jsonP = res.end = res.sendStatus = function() { 
        return this;
    }
  });
    
  next();
});