【问题标题】:UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT] - setInterval & Axios.post error handlingUnhandledPromiseRejectionWarning: E​​rror [ERR_HTTP_HEADERS_SENT] - setInterval & Axios.post 错误处理
【发布时间】:2020-04-19 10:53:07
【问题描述】:

我已尝试通过 Google 搜索来处理此警告。但是,由于我无法解决此警告,所以我在问这个问题。

以下警告是我现在面临的:

(node:39452) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:485:11)
    at ServerResponse.header 
...
    at ServerResponse.send 
...
    at ServerResponse.json 
...
    at ServerResponse.send 
...
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Timeout.priceAlarm [as _onTimeout] 
(node:39452) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)

当调用“priceAlarm”时,没关系。但是,当“intervalPriceAlarm = setInterval(priceAlarm, 3000, res, chatId);”时完成后,它会在 axios.post ... catch(error) 部分显示警告。

有没有人有好主意来处理它?

谢谢。

function priceAlarm(res, chatId) {
                axios
                  .get(url)
                  .then((response) => {
                    currentBtcBitfinexUsd = getPrice(
                      response.data.tickers,
                      "BTC",
                      "USD",
                      "bitfinex"
                    );

                    axios
                      .post( `${telegramBotUrl}${apiToken}/sendMessage`, {
                        chat_id: chatId,
                        text:
                          "\nBitfinex- BTC(USD):" +
                          currentBtcBitfinexUsd,
                      })
                      .then((response) => {
                        res.status(200).send(response);
                      })
                      .catch((error) => {
                        res.send(error); //****this part shows an error!*****
                      });

                  })
                  .catch((error) => {
                    console.log(error);
                  });
} 
function intervalAlarm(res,chatId){
  if (alarmFlag == 1 && intervalPriceAlarm == null) {
    intervalPriceAlarm = setInterval(priceAlarm, 3000, res, chatId);
    console.log(intervalPriceAlarm); //need to remove it
  }else{
    console.log("doing nothing");
  }
}
app.post("/", (req,res) =>{ 
     const chatId = req.body.message.chat.id;
     const sentMessage = req.body.message.text;

     if (sentMessage.match(/price/gi)) {
       priceAlarm(res, chatId); //No problem at all
     } else if (sentMessage.match(/start/gi)) {
       alarmFlag=1;       
       res.status(200).send({});
     } else if(sentMessage.match(/stop/gi)){
       alarmFlag=0;
       res.status(200).send({});
     } else {
       res.status(200).send({});
     }
    intervalAlarm(res,chatId);  // here setInterval part.
});

【问题讨论】:

    标签: javascript express axios


    【解决方案1】:

    这是一个服务器端错误,因为服务器无法重写已发送给客户端的响应的 HTTP 标头。因此,你不能 res.send() 两次相同的 res,但你可以在你的代码中这样做

    // here the first time
    priceAlarm(res, chatId); //No problem at all
    
    // here the second time
    intervalAlarm(res,chatId);  // here setInterval part.
    

    您必须重写代码,因为这是 HTTP 的基本行为,服务器在发送响应后无法向客户端发送数据。所以这不是一个明确的问题,这是一个 HTTP 限制。如果您希望您的服务器能够将数据“推送”到您的客户端,则必须改用 websockets。

    【讨论】:

    • "服务器在发送响应后无法向客户端发送数据。" -> 关于这个,是因为“priceAlarm”一直以相同信息的间隔执行吗?顺便说一句,为什么它会在“res.send(error);”处显示错误消息部分?
    • @ghisooo intervalAlarm 调用 priceAlarm 执行 res.send,因此当您在同一个中间件处理程序中执行 priceAlarmintervalAlarm 时,您在同一个中间件处理程序中调用 res.send 两次res 对象,这不可能发生
    • 谢谢。它会在间隔内不断发送具有相同“res”的响应...
    • 对了,不使用 res.send 部件可以吗?在“axios.post ... .then((response) => {res.status(200).send(response); }).catch((error) => {res.send(error); }); “? ..
    • 好吧,这取决于你想做什么
    猜你喜欢
    • 1970-01-01
    • 2019-10-16
    • 2020-12-16
    • 2020-02-14
    • 2021-11-19
    • 2019-01-30
    • 2020-05-04
    • 2021-08-21
    • 1970-01-01
    相关资源
    最近更新 更多