最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

如何解决节点js中的“将标头发送给客户端后无法设置标头?”的错误?

网站源码admin16浏览0评论

如何解决节点js中的“将标头发送给客户端后无法设置标头?”的错误?

如何解决节点js中的“将标头发送给客户端后无法设置标头?”的错误?

我已经大约6次不同的时间重写了以下函数,但仍然收到“无法将标头发送给客户端后设置”错误。我已经找到了关于诺言主题的几篇文章,但仍然无法弄清楚:

  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:未处理的承诺拒绝。该错误是由于在没有catch块的情况下抛出异步函数而产生的,或者是由于拒绝未使用.catch()处理的承诺。 (拒绝ID:1)(节点:29820)[DEP0018] DeprecationWarning:已弃用未处理的承诺拒绝。将来,未处理的承诺拒绝将终止Node.js进程,非零退出代码。

回答如下:

有两种使用诺言的方法。您可以使用then / catch回调,也可以使用async / await允许您同步编写它们。

然后/捕获方法

// 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定义之后未定义任何内容,否则它将运行before promise得以解决(这与直觉相反,因为将代码B放在代码B之后应该使A在B之前运行)

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

article应该可以帮助您更好地理解诺言...

希望这有帮助...

发布评论

评论列表(0)

  1. 暂无评论