如何使慢连接中间件超时并返回节点响应?

max*_*man 5 javascript node.js node-http-proxy node.js-connect

我有一个 Node 服务器,它使用 Connect 插入一些中间件,尝试转换来自 node-http-proxy 的响应流。有时,这种转换可能会非常慢,在这种情况下,最好简单地返回不包含转换或包含其部分应用程序的响应。

在我的应用程序中,我尝试在转换中间件的上下文中在几毫秒后setTimeout调用。next这通常有效,但会暴露一个竞争条件,如果中间件已经调用next然后setTimeout触发并执行相同的操作,则会出现如下错误:Error: Can't set headers after they are sent.

最终,我演变了以实例作为其第一个参数setTimeout进行调用,然后在我的中间件链中会捕获该错误并假设将开始通过 发送响应。这很有效,令人惊讶的是我可以将超时设置为几乎为零,并且响应会发生得更快并且更完整。nextErrorres.headersSentfalseres.end.call(res)

我觉得最后一种方法有点破解,并且不能免受相同竞争条件的影响,但也许看起来更有弹性。所以我想知道 Node 和 Connect 有什么样的惯用方法来处理这种事情。

我怎样才能让缓慢的中间件超时并简单地返回响应流?

目前,这似乎或多或少达到了我想要的效果,但又感觉有点恶心。

let resTimedout = false;
const timeout = setTimeout(() => {
  if (!resTimedout) {
    resTimedout = true;
    next();
  }
}, 100);


getSelectors(headers, uri, (selectors) => {
  const resSelectors = Object.keys(selectors).map((selector) => {
    ...
  };

  const rewrite = resRewrite(resSelectors);
  rewrite(req, res, () => {
    if (!resTimedout) {
      resTimedout = true;
      clearTimeout(timeout);
      next();
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

You*_*end 0

setTimeout 返回超时的 id,因此您可以运行 clearTimeout 并传入该 id。因此,当转换完成后,只需在调用下一步之前清除超时即可。

var a = setTimeout(()=>{}, 3000);
clearTimeout(a);
Run Code Online (Sandbox Code Playgroud)

https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout