【问题标题】:Getting Error: Can't set headers after they are sent出现错误:发送后无法设置标题
【发布时间】:2019-07-17 08:43:08
【问题描述】:

我正在尝试在 Node 中实现搜索功能,猫鼬。
我喜欢按名称或艺术家搜索两个参数。如果两者中的任何一个与当前数据库匹配,它应该返回值(使其变得安静)

但是,它正在发送响应Error: Can't set headers after they are sent.
Unhandled promise rejections are deprecated 甚至我得到的响应都是空的

我正在尝试在其中执行两个查询,我认为这可能是问题所在。我应该如何编写它,或者编写这些类型的功能的正确方法是什么

这是我当前的代码

app.get('/search/:textValue', controller.findData)

和 findData

exports.findData = (req, res)=>{

    const searchParam = req.params.textValue;
    let storeResult = []
    if(searchParam==null|| searchParam == undefined || searchParam==""){
        return res.status(500).json("Send a valid input")
     }
  else{
        Song.find({artists: new RegExp(searchParam, "i")}).lean().then((data)=>{
            storeResult[0].push(data)
        }).catch((err)=>{
            return res.send(err)
        })

        Song.find({name: new RegExp(searchParam, "i")}).lean().then((data)=>{
            storeResult[1].push(data)
        }).catch((err)=>{
            return res.send(err)
        })

        return res.send(storeResult)
    }
}

他们对单个查询工作得很好,这里应该做些什么改变?

【问题讨论】:

    标签: node.js mongodb rest mongoose


    【解决方案1】:

    在填写storeResult 之前,您使用res.send(storeResult) 的方式。为何如此?您使用尚未调用的 .then() 回调填充它。

    尝试链接您的 then 回调。

     Song.find({artists: new RegExp(searchParam, "i")}).lean()
    .then((data)=>{
        storeResult.push(data);
    })
    .then(() => {
        Song.find({name: new RegExp(searchParam, "i")}).lean()
        .then((data)=>{
    
            storeResult.push(data)
        })
        .then(() => {
            console.log(storeResult)
            res.send(storeResult)
        })  
    })
    .catch((err)=>{
        console.log("Here is error")
        console.log(err)
        res.send(err)
    })
    }
    

    提示。调试器中的单步调试有助于解决此类代码。

    【讨论】:

    • 对不起,我忘记了异步行为:-(
    • 感谢您的帮助,但是,我尝试使用您的代码,缺少一些括号,最终我得到了一个嵌套的承诺
    • 抱歉有错别字。感谢您修复它们。
    • 感谢您的回答,忘记异步行为是我的愚蠢
    【解决方案2】:

    试试这个:

    exports.findData = (req, res)=>{
        let count=0;
        const searchParam = req.params.textValue;
        let storeResult = []
        if(searchParam==null|| searchParam == undefined || searchParam==""){
            return res.status(500).json("Send a valid input")
         }
      else{
            Song.find({artists: new RegExp(searchParam, "i")}).lean().then((data)=>{
                storeResult[0].push(data)
            }).catch((err)=>{
                count++;
                return res.send(err)
            })
            if(count == 0) {
                Song.find({name: new RegExp(searchParam, "i")}).lean().then((data)=>{
                    storeResult[1].push(data)
                }).catch((err)=>{
                    count++;
                    return res.send(err)
                })
            }
            if(count == 0) {
                return res.send(storeResult)
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      问题

      1. 您从空数组 let storeResult = [] 开始
      2. 然后访问它的第一个元素(不存在)storeResult[0].push(data)
      3. 这将触发您的catch 回调。然后做一个res.send(err)
      4. 即使您调用了return,它仍然会在(req, res) => {} 中继续。这是因为return 仅适用于(err) => { // } 回调
      5. storeResult[1].push(data) 相同
      6. 最后您调用return res.send(storeResult),它有效地完成了您的(req, res) => {} 回调并向客户端返回另一个响应

      解决方案

      当你推送到 storeResult 数组时,省略索引。像这样

      storeResult.push(data)
      

      注意

      即使正确推送,访问数据库时也可能发生错误。这就是为什么你需要像O. Jones answer says

      这样链接你的回调

      【讨论】:

        猜你喜欢
        • 2017-05-31
        • 2015-11-13
        • 2015-03-07
        • 2020-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-18
        相关资源
        最近更新 更多