解决“Cannot set headers after they are sent to the client”及异步问题

问题


NodeJs+express+mongoDB接口中,在循环中写`res.json`时会报错(Cannot set headers after they are sent to the client

 解决方法

  • 循环外面定义一个变量为`false`
  • 在循环中要写`res.json`的地方让其变为`true`
  • 在循环外面判断该变量为`true`时写`res.json`

具体代码实现

var isShow = false;   //定义开关变量
//loadcurr为数组,具体内容省略了
loadcurr.forEach(item => {
    Stock.findOneAndUpdate({             //Stock是用来连接数据库集合的
       _id: ObjectId(item._id)
        }, {
            $set: {
            //此处省略要修改的内容
                。。。。。。
            }
        },
        function (err, data) {
            if (err) {
                console.log(err)
            } else {
            //此处应该写res.json,但是为了解决报错让前面定义的变量为true
                isShow = true
                console.log('1', isShow);
            }
        })
})
console.log('2', isShow);
if (isShow == true) {
    res.json({
        status: "200"
    })
}


这样就可以成功解决Cannot set headers after they are sent to the client的错啦!!!

注意:

如果上面的代码执行顺序是先打印了console.log('2', isShow);后打印console.log('1', isShow);,说明存在异步,因此用异步解决即可,具体实现如下所示(若顺序是先执行console.log('1', isShow);后执行console.log('2', isShow);就是正确的):

  • 若返回值不是promise用以下方法
var isShow = false;
    (async function(){
        await new Promise((resolve, reject) => {
            //loadcurr为数组,具体内容省略了
            loadcurr.forEach(item => {
                //Stock是用来连接数据库集合的
                Stock.findOneAndUpdate({
                    _id: ObjectId(item._id)
                }, {
                    $set: {
                        //此处省略要修改的内容
                        。。。。。。
                    }
                },
                function (err, data) {
                    if (err) {
                        console.log(err)
                    } else {
                        resolve(isShow = true)
                        console.log('1', isShow);
                    }
                })
            })
            
        })
        
        console.log('2', isShow);
            if (isShow == true) {
                res.json({
                    status: "200"
                })
            }
         
    })()
  • 若返回值是promise用以下方法
var isShow = false;
    (async function(){
        //loadcurr为数组,具体内容省略了
        await loadcurr.forEach(item => {
            //Stock是用来连接数据库集合的
            _id: ObjectId(item._id)
        }, {
              $set: {
              //此处省略要修改的内容
              。。。。。。
           }
         },
            function (err, data) {
                if (err) {
                    console.log(err)
                } else {
                    isShow = true
                    console.log('1', isShow);
                }
            })
        })
            
        console.log('2', isShow);
            if (isShow == true) {
                res.json({
                    status: "200"
                })
            }
         
    })()

 
好啦,以上就是解决循环里面写res.json报错问题及解决异步问题!在这两个问题没少费工夫??????

有问题欢迎指出,若有更好的解决方案欢迎在下面??????分享哦!!!

发布了93 篇原创文章 · 获赞 60 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43363871/article/details/101037279