为什么函数在return语句后继续运行?

时间:2020-03-28 18:06:35

标签: javascript firebase express

我正在运行以下代码,尝试删除不存在的“尖叫”:

// Delete a scream
exports.deleteScream = (req, res) => {
  const document = db.doc(`/screams/${req.params.screamId}`);
  document.get()
    .then(doc => {
      if(!doc.exists){
        console.log("1")
        return res.status(404).json({ error: 'Scream not found'});
        console.log("2")
      }
      if(doc.data.userHandle !== req.user.handle){
        return res.status(403).json({ error: 'Unathorized'});
      } else {
        return document.delete();
      }
    })
    .then(() => {
      console.log("3")
      return res.json({ message: 'Scream deleted successfully'});
      console.log("4")
    })
    .catch(err => {
      console.error(err);
      console.log("5")
      return res.status(500).json({ error: err.code });
    });
};

控制台日志显示以下内容:

>  1
>  3
>  Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
>      at ServerResponse.setHeader (_http_outgoing.js:516:11)
>      at ServerResponse.header (/Users/sm/projects/socialape/functions/node_modules/express/lib/response.js:771:10)
>      at ServerResponse.send (/Users/sm/projects/socialape/functions/node_modules/express/lib/response.js:170:12)
>      at ServerResponse.json (/Users/sm/projects/socialape/functions/node_modules/express/lib/response.js:267:15)
>      at /Users/sm/projects/socialape/functions/handlers/screams.js:227:18
>      at processTicksAndRejections (internal/process/task_queues.js:93:5) {
>    code: 'ERR_HTTP_HEADERS_SENT'
>  }
>  5
>  (node:4032) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
>      at ServerResponse.setHeader (_http_outgoing.js:516:11)
>      at ServerResponse.header (/Users/sm/projects/socialape/functions/node_modules/express/lib/response.js:771:10)
>      at ServerResponse.send (/Users/sm/projects/socialape/functions/node_modules/express/lib/response.js:170:12)
>      at ServerResponse.json (/Users/sm/projects/socialape/functions/node_modules/express/lib/response.js:267:15)
>      at /Users/sm/projects/socialape/functions/handlers/screams.js:233:30
>      at processTicksAndRejections (internal/process/task_queues.js:93:5)
>  (node:4032) 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:4032) [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.

我希望该函数在404响应时停止执行,但看起来除了then块之外,还同时执行了两个catch块。为什么会这样?

1 个答案:

答案 0 :(得分:2)

如果您在then函数内部返回,则仅返回该anonymous function。它不是父母的归还。您应该扔exception并返回渔获。

const document = db.doc(`/screams/${req.params.screamId}`);
document
  .get()
  .then(doc => {
    if (!doc.exists) throw new Error(404);
    return doc;
  })
  .then(doc => {
    if (doc.data.userHandle !== req.user.handle) {
      throw new Error(403);
    } else {
      document.delete();
    }
    return doc;
  })
  .then(() => {
    res.json({ message: "Scream deleted successfully" });
  })
  .catch(error => {
    switch (error.message) {
      case 403:
        res.status(error.message).send({ error: "Unathorized" });
        break;
      case 404:
        res.status(error.message).send({ error: "Scream not found" });
        break;
      default:
        res.status(error.message).send({ error: error.message });
        break;
    }
  });