出现错误:发送标头后无法设置标头

时间:2019-02-23 11:03:54

标签: node.js mongodb rest mongoose

我正在尝试在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)
    }
}

他们可以很好地处理单个查询,应该在此处进行哪些更改?

3 个答案:

答案 0 :(得分:1)

尝试一下:

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)
        }
    }
}

答案 1 :(得分:1)

在填写res.send(storeResult)之前,您使用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 :(得分:1)

问题

  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

之类的回调的原因