express响应超时应该怎么做?
发布于 8 年前 作者 lzszone 10626 次预览 最后一次回复是 8 年前 来自 问答
现在项目遇到了一点问题,表现是命令行有打印,能收到请求,但是不吐数据, 经坛友指点,现在怀疑是资源没释放导致的,所以想加一个超时处理, 然后看了express的教程,貌似可以用connect-timeout中间件解决 但是这个中间件在项目里始终要报can’t set headers after they are sent. 目前也没什么好的解决办法,各位有主意吗?
21 回复
你异步没处理好吧!
来自酷炫的 CNodeMD
@Aoqin 问题是,我用express-generator生成的新项目引用这个模块仍然报错啊
能放出代码看一下吗?
来自酷炫的 CNodeMD
虽然楼主没贴代码,但根据我踩坑的经验 把调用中间件的next()改成 return next()试试
代码 next 没有处理好
抱歉各位,上午电脑出问题了@cctv1005s @Yuki-Minakami @htoooth 现在也没办法贴代码 ,不过代码大概就这样子:
当天我没注意看文档,昨天意识到了,它是说不建议用作顶级中间件是吧 当作为顶级中间件的时候,是不是每调用一个中间件都要在后面再调用一次handler?@Yuki-Minakami 那他也没说不当顶级中间件该咋使呀。。。T T 我待会试试你的
return next();各位 再看看首先,你的错误和timeout是不是顶层中间件没关系 第二,如果做顶层中间件也可以,你也可以在所有中间件调用的最后调一次handler,就像这样
但这样不推荐,因为如果中间有太多中间件就不好控制整体的执行时间 最后,你目前贴的代码看不出毛病,但八九不离十是哪个异步的中间件前面需要加return
@Yuki-Minakami 那应该在哪里使用timeout中间件呢? 应该是在具体业务流程开始之前使用吗?
帖一下全部代码:
当我访问users的时候,页面在5秒时会打印503报错页,是对的 但是10秒的时候,app会报错:
@Aoqin @cctv1005s @Yuki-Minakami @htoooth ,大家再看看,感激不尽
问题就是出在10秒后会调用res.send方法,但是应该怎么写呢,在正常的逻辑中,肯定要涉及到渲染输出到res的; 根据这个timeoutHandler的写法来看,是不是在设计的时候应该把渲染输出到res和数据库操作等有可能超时的操作分离,然后在每一处可能造成超时的中间件调用完成之后加上app.use(timeoutHandler);?
嗯,大致明白了,和开始想的不大一样,不好意思前面可能误导你了
超时时间设置了5秒,ok,5秒后超时返回了错误码,这个http请求就结束了 然而10秒后还有个res需要输出,对一个已经结束的进行响应,这就是错误的原因
要改的话就把app.use(’/users’, users);这句放到外面
这样10秒后就没有cant send header again的错误了,但这样就舍本逐末了
根本问题应该是面对一个未知耗时的异步操作,怎么用connect-time来管理 这部分让我回家想想…
你报的这个错误我在egg里不使用yield的时候也遇到过
app.set(‘view engine’, ‘pug’);这是个什么模板
@Yuki-Minakami 有点搅,这中间件github才两百星,3个未解决的issue是关于这个问题的,貌似啊,记不清了
@yangkuo1993 原来的jade
@wangchaoduo 能具体回忆下吗
这个目前还真没啥好办法, 你这个场景其实只要想办法让10秒后的那个回调不执行就好了 具体可以使用事件监听,如果超过了timeout时间,就清除掉后面的setTimeout
@lzszone 他的问题对你的应该没啥帮助
@Yuki-Minakami 对,思路是这样的,他源码很短90行,然后看了下,感觉这玩意不好用。。。怪不得才200星,剩下的我自己想吧,谢谢
楼主我写了篇文章关于超时处理的,可以看看 https://cnodejs.org/topic/5936cd57538dbcaa6bc7dd8f
你可以设个类似开关的值,只要res.send后就变为false,发送前先判定次
来自酷炫的 CNodeMD