javascript - Node.js出现 "Cannot set headers after they are sent to the client"错误怎么解决?

标签 javascript node.js firebase google-cloud-firestore google-cloud-functions

我已经重写了以下函数大约 6 次,但仍然收到“将 header 发送到客户端后无法设置 header ”错误。我找到了几篇关于 Promise 主题的帖子,但仍然无法弄清楚:

  1. Error: Can't set headers after they are sent to the client
  2. Cannot set headers after they are sent to the client
  3. Error: Setting header after it is sent - Help me understand why?

以下函数适用于论坛,在提交评论时触发。它检查论坛帖子是否存在,以及父评论是否存在(如果是子评论)。我正在使用 firestore。

index.js

const functions = require('firebase-functions');
const app = require('express')();
const {postOneForumComment,
} = require('./handlers/forumPosts');

app.post('/forumPost/:forumPostId/:parentId/comment', FBAuth, postOneForumComment);

exports.api = functions.https.onRequest(app);

forumPosts.js

// submit a new comment
exports.postOneForumComment = (req, res) => {
  if (req.body.body.trim() === '')
  return res.status(400).json({ comment: 'Must not be empty' });

 const newComment = {
   body: req.body.body,
   forumPostId: req.params.forumPostId,
   parentId: req.params.parentId
 };

 db.doc(`/forumPosts/${req.params.forumPostId}`)                  //check to see if the post exists
   .get()
   .then((doc) => {
     if (!doc.exists) {
       return res.status(404).json({ error: 'Post not found' });
     }
     else if (req.params.forumPostId !== req.params.parentId) {   //check to see if the comment is a subcomment
       return db.doc(`/forumComments/${req.params.parentId}`)     //check to see if the parent comment exists
         .get();
     }
     return "TopLevelComment";
   })
   .then((data) => {
     if (data === 'TopLevelComment' || data.exists) {
       return db.collection('forumComments').add(newComment);     //post the comment to the database
     }
     return res.status(500).json({ error: 'Comment not found' });
   })
   .then(() => {
     res.json(newComment);
   })
   .catch((err) => {
     console.log(err.message);
     res.status(500).json({ error: 'somethign went wrong' });
   });
 };

错误:

(node:29820) 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:29820) [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.

最佳答案

有两种使用 Promise 的方法。您可以使用 then/catch 回调,也可以使用 async/await 来同步编写它们.

then/catch方法

// Some code before promise

somePromise.then(() => {
    // Some code after promise action is successful
}).catch(err => {
    // Some code if promise action failed
})

// Some code after promise definition you think should run after the above code
// THIS IS WHAT IS HAPPENING WITH YOUR CODE

异步/等待方法

// Some code before promise
await somePromise;
// Some code after promise action is successful

引入后一种方法是为了避免 callback hell problem看来这就是您的错误产生的原因。

当使用回调回调时,您必须确保在 Promise 定义之后没有定义任何内容,否则它将在 Promise 解析之前运行(这是违反直觉的,因为将代码 B 放在代码 B 之后应该使 A在 B 之前运行

您的错误是因为您的回调可能在响应发送后运行,而 Express 不允许您为请求发送多个响应。 您应该确保回调中存在调用 res.sendres.json 的位置。

这个article应该可以帮助您更好地理解 promise ...

希望这有帮助...

关于javascript - Node.js出现 "Cannot set headers after they are sent to the client"错误怎么解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59697207/

相关文章:

javascript - 在 Angular 和 Node 中使用 socket.io 时出现 404 错误

javascript - 创建图片库时如何解决全局变量问题?

javascript - 我如何在 javascript 中验证年份文本框?

json - 如何从 JSON 文件获取值并在网站上显示

html - 使用 node.js 中的 XSLT 样式表将 xml 转换为 html

android - 有没有办法在不加载Android中所有节点数据的情况下获取节点的子节点数?

javascript - 我们如何通过javascript检查浏览器的自动更新是否启用

javascript - 重新加载快速中间件的正确方法是什么?

javascript - 云 Firestore : Update fields in nested objects with dynamic key

javascript - "ref.off()"是读取数据后与 Firebase 数据库断开连接的正确方法吗?