使用异步/等待时为什么会收到多个响应?

时间:2019-11-20 02:44:49

标签: javascript html rest asynchronous async-await

我正在为一个班级编写一个简单的投票网络api。我目前正在使用PUT,并且我的代码正在运行,但是在命令行终端中出现了一个奇怪的错误。这是我用来调用PUT的代码:

async addVotes(item) {
      try {
            let response = await axios.put("/api/candidates/" + item._id);
            this.getItems();
            return true;
          }
          catch (error) {
            console.log(error);
          }
          console.log(item.name + " is checked");
    },

async submitVotes(items) {
      for (var item of this.items) {
        if (item.selected) {

          this.addVotes(item);
        }
        else {
          console.log(item.name + " is not checked");
        }
      }
    },

这是api的PUT代码:

app.put('/api/candidates/:id', async(req, res) => {
  console.log("initiated put(edit) request");
  try {
    let candidate = await Candidate.findOne({ _id: req.params.id });
    candidate.numVotes += 1;
    candidate.save();
    res.send(candidate);
    res.sendStatus(200);
  }
  catch (error) {
    console.log(error);
    res.sendStatus(500);
  }
});

我在说这个错误:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:470:11)
    at ServerResponse.header (/var/www/html/MidRev/node_modules/express/lib/response.js:771:10)
    at ServerResponse.contentType (/var/www/html/MidRev/node_modules/express/lib/response.js:599:15)
    at ServerResponse.sendStatus (/var/www/html/MidRev/node_modules/express/lib/response.js:357:8)
    at app.put (/var/www/html/MidRev/start.js:102:9)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:13246) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:470:11)
    at ServerResponse.header (/var/www/html/MidRev/node_modules/express/lib/response.js:771:10)
    at ServerResponse.contentType (/var/www/html/MidRev/node_modules/express/lib/response.js:599:15)
    at ServerResponse.sendStatus (/var/www/html/MidRev/node_modules/express/lib/response.js:357:8)
    at app.put (/var/www/html/MidRev/start.js:106:9)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:13246) 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: 1)
(node:13246) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

从我在线研究的内容中,我得到了这个错误,因为我得到了多个响应,但是我正在使用async / await,所以我不明白为什么我会收到该错误。

2 个答案:

答案 0 :(得分:3)

您将状态添加到响应的方法不正确。

代替

res.send(candidate);
res.sendStatus(200);

您应该这样做

res.status(200).send(candidate)

sendStatus在设置状态代码的顶部发送“ OK”消息。您可以在https://expressjs.com/en/api.html

处参考Express API参考。

答案 1 :(得分:2)

问题出在您的PUT API实现中,您在其中两次发送了响应:

  1. res.send(候选人); //将json响应发送回客户端
  2. res.sendStatus(200); //尝试发送响应状态

因此,如果您要发送json响应,则无需显式发送响应状态。

res.send(candidate); OR res.json(candidate);

但是,如果要指定响应状态,则可以执行如下链接:

res.status(500).send({ error: "boo" });