express响应问题(已解决)
发布于 6 个月前 作者 xiaobai2017666 1024 次浏览 来自 问答
user.post('/dialog',function (req,res,next) {
  res.header('Access-Control-Allow-Origin', '*');
  //mongodb数据库查询
  types.find(function (err,result1) {
    if(err){
      console.log(err);
    }
	//数据库文档的是否查找到的标识
    let typesFindFlag=true;
    let dialogsFindFlag=true;
    for(let i=0,len=result1.length;i<len;i++){
      let reg = new RegExp(result1[i].title);
      if (reg.test(req.body.text)) {
        dialogs.find({ text: 'type' }, function (err, result2) {
          if (err) {
            console.log(err);
          }
          result2[0].dialog += '<ol>';
          for(let j=0,len=result1[i].list.length;j<len;j++){
            result2[0].dialog += '<li><a href="#/work/' + result1[i].list[j] + '">' + result1[i].list[j]+'</a></li>';
          }
          result2[0].dialog += '</ol>';
		  //报错行
          res.send(result2[0]);
        })
        typesFindFlag=false;
        break;
      }
    }
    if(typesFindFlag){
      dialogs.find(function (err,result) {
        if(err){
          console.log(err);
        }
        for(let i=0,len=result.length;i<len;i++){
          let reg=new RegExp(result[i].text);
          if(reg.test(req.body.text)) {
		  	//报错行
			res.send(result[i]);
            dialogsFindFlag=false;
            break;
          }
        }
      })
    }
    if (dialogsFindFlag) {
      dialogs.find({ text: 'nothing' },function (err,result) {
        if(err) {
          console.log(err);
        }
		//报错行
		res.send(result[0]);
      })
    }
  })
})

场景是我频繁在一个时间段反复访问后出现报错 throw er; // Unhandled ‘error’ event ^

Error: Can’t set headers after they are sent. 网上查询分析后我觉得是第二次请求时,第一个请求未响应完成,然后在第二次请求时产生了两次响应。 但是不知道如何进行处理,求帮助,嘤嘤嘤

11 回复

明显是一个请求多次响应了, 对于某一个请求,11行的for循环次数大于1 里面就会响应多次造成这个错误

不要再这样写代码了, 人生要有些追求

@ouyangxuanyun 我循环里面if加了break 。 并且我的数据库控制了,if条件最多满足一次

@xiaozhongliu 请问我的代码有什么问题吗

异步编程不是你这样玩的

一眼看去就让人头疼, 这是最大的问题

原因不是for循环的请求多次响应。 而是for循环外的第二个if分支没有遵循异步编程思想。导致res.send执行了两次。 QQ图片20180903124110.png 把第二个if分支放在前者查询执行结束后就可以了

user.post('/dialog',function (req,res) {
  res.header('Access-Control-Allow-Origin', '*');

  types.find(function (err,result1) {
    if(err){
      console.log(err);
    }
    let typesFindFlag=true;
    let dialogsFindFlag=true;
    for(let i=0,len=result1.length;i<len;i++){
      let reg = new RegExp(result1[i].title);
      if (reg.test(req.body.text)) {
        dialogs.find({ text: 'type' }, function (err, result2) {
          if (err) {
            console.log(err);
          }
          result2[0].dialog += '<ol>';
          for(let j=0,len=result1[i].list.length;j<len;j++){
            result2[0].dialog += '<li><a href="#/work/' + result1[i].list[j] + '">' + result1[i].list[j]+'</a></li>';
          }
          result2[0].dialog += '</ol>';
          res.send(result2[0]);
        })
        typesFindFlag=false;
        break;
      }
    }
    if(typesFindFlag){
      dialogs.find(function (err,result) {
        if(err){
          console.log(err);
        }
        for(let i=0,len=result.length;i<len;i++){
          let reg=new RegExp(result[i].text);
          if(reg.test(req.body.text)) {
            res.send(result[i]);
            dialogsFindFlag=false;
            break;
          }
        }
		//修改部分。。。
        if (dialogsFindFlag) {
          dialogs.find({ text: 'nothing' }, function (err, result) {
            if (err) {
              console.log(err);
            }
            res.send(result[0]);
          })
        }
      })
    }
  })
})
user.post('/dialog', async function (req, res) {
    res.header('Access-Control-Allow-Origin', '*');
    try {
        const typesRes = await fun1()
        for (let val of typesRes) {
            const reg = new RegExp(val.title)
            if (reg.test(req.body.text)) {
                const dialogsRes = await fun2({ text: "type" })
                const data = dialogsRes[0]
                const str = val.list.map(v => `<li><a href="#/work/${v}">${v}</a></li>`).join('')
                data.dialog += `<ol>${str}</ol>`
                return res.send(data)
            }
        }

        const flag1 = await fun2()
        for (let val of flag1) {
            const reg = new RegExp(val.text)
            if (reg.test(req.body.text)) {
                return res.send(val);
            }
        }

        const flag2 = await fun2({ text: 'nothing' })
        return res.send(flag2[0])

    } catch (e) {
        console.log(e)
    }
})


function fun1() {
    return new Promise((resolve, reject) => {
        types.find((err, result) => {
            if (err) {
                reject(err)
            } else {
                resolve(result)
            }
        })
    })
}

function fun2(options = {}) {
    return new Promise((resolve, reject) => {
        dialogs.find(options, function (err, result) {
            if (err) {
                reject(err)
            } else {
                resolve(result)
            }
        })
    })
}

试试这样写,舒服一点

看着你的代码就知道,你不适合写nodejs,promise被狗吃了吗

来自酷炫的 CNodeMD

回到顶部