Почему функция продолжает работать после оператора return? - PullRequest
0 голосов
/ 28 марта 2020

Я выполняю следующий код, пытающийся удалить «крик», который не существует:

// 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 Ответ

2 голосов
/ 28 марта 2020

Если вы вернетесь внутрь функции 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;
    }
  });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...