Stack Overflow对此错误有很多疑问。每个人都有其背景。我已尝试应用大多数建议的解决方案,但没有一个工作。我也是koa和猫鼬的新手
"use strict"
const Koa = require('koa')
const Router = require('koa-router')
const router = new Router()
const mongoose = require('mongoose')
const Pug = require('koa-pug')
const app = new Koa()
const KoaBody = require('koa-body')
const koaBody = new KoaBody()
mongoose.Promise = global.Promise
mongoose.connect('mongodb://localhost/my_db', {useMongoClient: true, promiseLibrary: global.Promise})
const personSchema = mongoose.Schema({
name: String,
age: Number,
nationality: String
})
const Person = mongoose.model("Person", personSchema)
const pug = new Pug({
viewPath: '.',
})
router.get('/person', async ctx => {
ctx.render('person')
})
router.post('/person', koaBody, async (ctx, next) => {
const personInfo = ctx.request.body
if (!personInfo.name || !personInfo.age || !personInfo.nationality) {
return ctx.render('show_message', {message: "Sorry, you provided wrong info", type: "error"})
}
else {
const newPerson = new Person({
name: personInfo.name,
age: personInfo.age,
nationality: personInfo.nationality
})
if (ctx.response.headerSent) console.log("sent 0")
newPerson.save(function (err) {
if (ctx.response.headerSent) console.log("sent 1")
if (err) {
return err
}
else {
if (ctx.response.headerSent) console.log("sent 2")
ctx.response.flushHeaders()
ctx.render('show_message', {
message: "New person added", type: "success", person: personInfo
})
}
})
}
})
pug.use(app)
app.use(router.routes())
app.listen(3000, () => {
console.log("We are listening for connections on the server")
})
当我执行代码时,我收到以下错误:
We are listening for connections on the server
sent 1
sent 2
events.js:182
throw er; // Unhandled 'error' event
^
Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:504:11)
at ServerResponse.setHeader (_http_outgoing.js:511:3)
at Object.set (C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\koa\lib\response.js:440:16)
at Object.set type [as type] (C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\koa\lib\response.js:310:12)
at Object.type (C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\delegates\index.js:92:31)
at Object.contextRenderer [as render] (C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\koa-pug\src\pug.js:107:15)
at C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\learn-koa\app.js:49:25
at C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\mongoose\lib\model.js:3835:16
at C:\Users\nahas\OneDrive\Code\Javascript\Node Modules\node_modules\mongoose\lib\services\model\applyHooks.js:162:20
at _combinedTickCallback (internal/process/next_tick.js:95:7)
at process._tickCallback (internal/process/next_tick.js:161:9)
我尝试通过在发送时登录控制台来确定标头的确切位置。正如您从错误输出中看到的那样,标题会在此行之后立即发送:
newPerson.save(function (err) {
这意味着猫鼬保存功能正在向用户发送标头。 怎么办这个问题?
答案 0 :(得分:1)
newPerson.save()
是一个异步函数。您将回调函数传递给它,在保存操作完成时调用该函数。然而,当它被调用时,您的路由器功能已经返回,因此已经发送的头部已经发送。
这是异步/等待模式发挥作用的地方。由于您已经处于异步功能中,所以您需要做的就是等待.save()
的结果。你可以等待承诺。幸运的是,如果你没有通过回调,mongoose .save()会返回一个承诺。这意味着你可以等待它。所以...
await newPerson.save()
ctx.render('show_message', {
message: "New person added", type: "success", person: personInfo
})
使用异步等待时,错误处理有点不同,或者再次正确完成错误处理;-)。
您将像在js中一样使用try / catch进行错误处理。
try{
await newPerson.save()
ctx.render(...)
}catch(err){
ctx.status=500
ctx.body="somthing went wrong"
}