Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当我尝试发出更新请求时,无法在将头发送到客户端后设置头_Javascript_Node.js_Mongodb_Express_Mongoose - Fatal编程技术网

Javascript 当我尝试发出更新请求时,无法在将头发送到客户端后设置头

Javascript 当我尝试发出更新请求时,无法在将头发送到客户端后设置头,javascript,node.js,mongodb,express,mongoose,Javascript,Node.js,Mongodb,Express,Mongoose,我正在尝试创建一个积垢。我已经创建了更新,但是当我尝试向邮递员请求时,我得到以下错误: 错误[ERR\u HTTP\u HEADERS\u SENT]:发送后无法设置头 给客户 在ServerResponse.setHeader(_http_outgoing.js:526:11) 在ServerResponse.header(E:\freebooks核心api\node\u modules\express\lib\response.js:771:10) 在ServerResponse.send(

我正在尝试创建一个积垢。我已经创建了更新,但是当我尝试向邮递员请求时,我得到以下错误:

错误[ERR\u HTTP\u HEADERS\u SENT]:发送后无法设置头 给客户 在ServerResponse.setHeader(_http_outgoing.js:526:11) 在ServerResponse.header(E:\freebooks核心api\node\u modules\express\lib\response.js:771:10) 在ServerResponse.send(E:\freebooks核心api\node\u modules\express\lib\response.js:170:12) 在ServerResponse.json(E:\freebooks核心api\node\u modules\express\lib\response.js:267:15) 在ServerResponse.send(E:\freebooks核心api\node\u modules\express\lib\response.js:158:21) 在Object.exports.success(E:\freebooks核心api\network\response.js:3:6) 在E:\freebooks core api\components\book\network.js:32:18 在processTicksAndRejections(internal/process/task_queues.js:97:5){代码: 'ERR_HTTP_HEADERS_SENT'}(节点:2844) 未经处理的PromisejectionWarning:错误[ERR\u HTTP\u HEADERS\u SENT]: 发送到客户端后无法设置标头 在ServerResponse.setHeader(_http_outgoing.js:526:11) 在ServerResponse.header(E:\freebooks核心api\node\u modules\express\lib\response.js:771:10) 在ServerResponse.send(E:\freebooks核心api\node\u modules\express\lib\response.js:170:12) 在ServerResponse.json(E:\freebooks核心api\node\u modules\express\lib\response.js:267:15) 在ServerResponse.send(E:\freebooks核心api\node\u modules\express\lib\response.js:158:21) 在Object.exports.error(E:\freebooks核心api\network\response.js:12:6) 在E:\freebooks核心api\components\book\network.js:34:16 在processTicksAndRejections(internal/process/task_queues.js:97:5)(节点:2844) 未处理的PromisejectionWarning:未处理的承诺拒绝。这 错误源于异步函数的内部抛出 没有拦截,或拒绝未处理的承诺 with.catch()。终止未处理承诺的节点进程 拒绝,请使用CLI标志
--未处理的拒绝=严格(请参阅
).
(拒绝id:1)(节点:2844)[DEP0018]拒绝警告:未处理
拒绝承诺是不推荐的。在未来,承诺拒绝
未处理的将使用
非零退出代码

正如我在错误中所读到的,这来自以下文件:

我的网络文件夹中的response.js

exports.success = function (req, res, data, status) {
  res.status(status || 200)
    .send({
      error: '',
      data
    })
}

exports.error = function (req, res, error, status, log) {
  console.log(log)
  res.status(status || 500)
    .send({
      error,
      data: ''
    })
}
和我的书(组件)文件夹中的network.js

但是,由于我正在调用控制器,并且错误正在该行上运行,因此代码如下:

const store = require('./store')

function getBooks () {
  return new Promise((resolve, reject) => {

    resolve(store.list())
  })
}

function addBook (book) {
  return new Promise((resolve, reject) => {
    if (!book) {
      reject('I reject')
      return false
    } else {

      resolve(book)
      store.add(book)
    }
  })
}

 function updateBook (id, book) {
  return new Promise( async (resolve, reject) => {
      if (!id || !book) {
          reject('Invalid data')
          return false
      } else {
        const result = await store.update(id, book)
        resolve(result)
      }

  })
}

function deleteBook (id) {
  return new Promise( async (resolve, reject) => {
      if (!id) {
          reject('Invalid data')
          return false
      } else {
        const result = await store.update(id)
        resolve(result)
      }

  })
}

module.exports = {
  addBook,
  getBooks,
  updateBook,
  deleteBook
}
最后,商店

const db = require('mongoose')
const Model = require('./model')

db.Promise = global.Promise
db.connect(`mongodb+srv://fewtwtwfwe:efwefwecwecw@ferwrtervsefwg/test?retryWrites=true&w=majority`, {
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then( () => {
    console.log(`Database connected`)
}).catch( err => {
    console.error(err)
})

function addBook(book) {
    const myBook = new Model(book)
    myBook.save()
}

async function getBooks() {
   const books =  await Model.find()
   return books
}

async function updateBook(id, book) {
    const foundBook = await Model.findOne({
        '_id':id
    })
    foundBook.book = book
    const newBook = await foundBook.save()
    return newBook
}

async function deleteBook(id) {
    const foundBook = await Model.findOne({
        '_id':id
    })
}


module.exports = {
    add: addBook,
    list: getBooks,
    update: updateBook,
    delete: deleteBook,
}

我修改了数据库连接的数据,因为我确信错误不在那里,我提出了其他请求,显然一切都很好。有什么想法吗?

对于每个传入的请求,您只能发送一个响应。这个特定的错误消息告诉您,您的代码正试图发送两个请求。大多数情况下,这是因为使用异步函数对代码进行了不正确的排序。这条路线似乎就是这样:

router.patch('/:id', function(req, res) {
  const { id } = req.params
  console.log(id)
  const book = req.body
  controller.updateBook(id, book)
    .then( data => {
        response.success(req, res, data, 200)
    }).catch( err => {
      response.error(req, res, 'Internal error', 500, err)
    }) 
  res.send('Ok')
})
首先,它执行:

controller.updateBook()
res.send('Ok');
然后,当异步操作运行时,它会执行:

controller.updateBook()
res.send('Ok');
然后,过了一段时间,
updateBook()
完成,它调用
.Then()
.catch()
处理程序,然后您尝试对同一请求发送另一个响应

似乎您应该完全删除
res.send('Ok')
,因为您希望根据
.then()
.catch()
处理程序中
updateBook()
的状态发送响应


在另一个完全不同的主题中,将承诺返回函数封装在另一个承诺中有点反模式,就像您在
updateBook()中所做的那样。我建议你改变这一点:

function updateBook (id, book) {
  return new Promise( async (resolve, reject) => {
      if (!id || !book) {
          reject('Invalid data')
          return false
      } else {
        const result = await store.update(id, book)
        resolve(result)
      }

  })
}
为此:

function updateBook (id, book) {
    if (!id || !book) {
        return Promise.reject('Invalid data');
    } else {
        return store.update(id, book);
    }
}
仅供参考,它是一种反模式的原因是它是不必要的代码,人们在错误处理中经常出错,这正是您所做的。如果
store.update()
被拒绝,则在
wait
周围没有
try/catch
来捕获该错误,因此该错误将丢失,您的承诺将永远不会得到解决或拒绝


您应该更改所有结构类似的函数以解决此问题。

对于每个传入请求,您只能发送一个响应。这个特定的错误消息告诉您,您的代码正试图发送两个请求。大多数情况下,这是因为使用异步函数对代码进行了不正确的排序。这条路线似乎就是这样:

router.patch('/:id', function(req, res) {
  const { id } = req.params
  console.log(id)
  const book = req.body
  controller.updateBook(id, book)
    .then( data => {
        response.success(req, res, data, 200)
    }).catch( err => {
      response.error(req, res, 'Internal error', 500, err)
    }) 
  res.send('Ok')
})
首先,它执行:

controller.updateBook()
res.send('Ok');
然后,当异步操作运行时,它会执行:

controller.updateBook()
res.send('Ok');
然后,过了一段时间,
updateBook()
完成,它调用
.Then()
.catch()
处理程序,然后您尝试对同一请求发送另一个响应

似乎您应该完全删除
res.send('Ok')
,因为您希望根据
.then()
.catch()
处理程序中
updateBook()
的状态发送响应


在另一个完全不同的主题中,将承诺返回函数封装在另一个承诺中有点反模式,就像您在
updateBook()中所做的那样。我建议你改变这一点:

function updateBook (id, book) {
  return new Promise( async (resolve, reject) => {
      if (!id || !book) {
          reject('Invalid data')
          return false
      } else {
        const result = await store.update(id, book)
        resolve(result)
      }

  })
}
为此:

function updateBook (id, book) {
    if (!id || !book) {
        return Promise.reject('Invalid data');
    } else {
        return store.update(id, book);
    }
}
仅供参考,它是一种反模式的原因是它是不必要的代码,人们在错误处理中经常出错,这正是您所做的。如果
store.update()
被拒绝,则在
wait
周围没有
try/catch
来捕获该错误,因此该错误将丢失,您的承诺将永远不会得到解决或拒绝

你应该改变一切