首页 > 解决方案 > 后台 API 调用导致服务器错误

问题描述

我有一个应用程序,我需要每 5 秒获取一次状态和消息。这些调用是在我的主页 AsyncApp.js 上进行的,该页面包含应用程序的框架(导航栏等......)。问题是当用户转到一个新页面,该页面有许多自己的 api 调用以获取它需要在组件中渲染页面所需的数据时,服务器崩溃并出现错误“发送后无法设置标题”。我知道这确实与标头无关,而是与同时进行许多 api 调用有关。

我尝试过使用 async 和 await ,它可以正常工作,直到一个具有很多自身 api 调用的页面在其中一个状态调用熄灭的同时呈现。我尝试使用 Promises,因为我认为 Promises 不会像 async 和 await 那样阻止程序运行,而是在其他活动正在进行时花点时间。我不知道承诺是否是正确的方法,我只是错误地使用它们,或者我可能需要设置子进程。我以前从未做过,所以我完全不熟悉。我对 nodejs 和 Web 开发非常陌生。

通知(){

const { dispatch } = this.props

this.newNotifications = setInterval( async () => {

  let data = { since_last_checked : this.state.sinceLastCheck }
  let res1 = await fetch('/api/getNotifications', {
    method:'POST',
    headers: {
      'Content-type': 'application/json',
      'accept': 'application/json'
    },
    body:JSON.stringify(data)
  })
  .then(res => res.json())
  .catch(err => console.log(err))
  .done()

  console.log("NOTIFICATIONS", res1)

  //if(res1 === undefined || res1.data === undefined || res1.data === null){
    //this.setState({redirect: true})
  //}

  //if(res1 !== undefined && res1.data !== null && res1.data.messages) dispatch(updateMessages(res1.data.messages.slice(9)))

  let res2 = await fetch('/api/getStatus')
  .then(res => res.json())
  .catch(err => console.log(err))
  .done()

  console.log("STATUS", res2)

  //if(res2 === undefined || res2.data === undefined || res2.data === null || res2.data.is_active === 'N' || res2.data.status === 'closed'){
    //this.setState({redirect: true})
  //}

}, 5000)

//我的请求正在由 websocket 完成

function getData(url, pugCommand){

  app.get(url, (req, res) => {

    console.log("URL", url)

    let parsedUrl = urltest.parse(url);
    let parsedQs = querystring.parse(parsedUrl.query);

    stompClient = new StompJs.Client({
        connectHeaders: { login: "statemanager", passcode: "Ion_1551" },
        brokerURL: brokerURL,
        reconnectDelay: 200,
        //debug: (str) =>  { console.log("DEBUG", str) },
        onConnect: () => { sendCommandToPUG(pugCommand[0], pugCommand[1],  pugCommand[2], stompClient, req.session.userID, req.session.pugSessionID); },
        onUnhandledMessage: (messageReply) => {

            reply = JSON.parse(messageReply.body);
            if(reply.status.errorOccured)
                console.log("PUG-SERVER RETURNED ERROR: " + reply.status.errorText);

            replyData = reply.data; //here is where you will find all the data that matches your query (eg: fields/rows)
            return res.json(reply);
            //stompClient.disconnect();
        },
    });
    stompClient.activate();

  });
}

//我在这里打电话

getData('/api/getStatus', ["GET_SESSION_STATUS", "SESSIONS",  { '' : ''}]);

发送后无法设置标头是通常的错误,但我相信我正在阻止导致此错误的事件循环。

标签: node.jsreactjsexpressredux

解决方案


.then(res => res.json()),您在代码中使用它两次的同一行,您不能发送 res 两次,您可以使用第一个响应来计算第二个响应。

您不应该同时使用 await 和 .then 块,如果您使用 await 那么响应将返回到分配的变量。

你可以像这样使用它 -

const promisify_fetch = promisify(fetch);
  let res1 = await promisify_fetch('/api/getNotifications', {
    method:'POST',
    headers: {
      'Content-type': 'application/json',
      'accept': 'application/json'
    },
    body:JSON.stringify(data)
  });
  if (!res) throw "error occurred"
  res1 = res1.json();

推荐阅读