【发布时间】:2017-01-18 02:30:52
【问题描述】:
我有一个 Node 服务器,它使用 Connect 插入一些中间件,这些中间件试图从 node-http-proxy 转换响应流。有时,这种转换可能会很慢,在这种情况下,最好只返回一个不包含转换或包含它们的部分应用的响应。
在我的应用程序中,我尝试使用setTimeout 在转换中间件的上下文中经过几毫秒后调用next。这通常有效,但会暴露一个竞争条件,如果中间件已经调用了next,然后setTimeout 触发并且发生同样的错误,看起来像:Error: Can't set headers after they are sent.
最终我将setTimeout 改进为以Error 实例作为其第一个参数来调用next,然后在我的中间件链中稍后会捕获该错误并假设res.headersSent 是false 将开始发送通过res.end.call(res)回复。这很奏效,令人惊讶的是,我可以将超时设置为几乎为零,并且响应会发生得更快并且是完整的。
我觉得最后一种方法有点像 hack 并且不能免受相同的竞争条件的影响,但可能看起来更有弹性。所以我想知道 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();
}
});
});
【问题讨论】:
-
可以看
Promise.race和async.racebluebirdjs.com/docs/api/promise.race.html,caolan.github.io/async/docs.html#race
标签: javascript node.js connect node-http-proxy