2017-09-27 57 views
0

Stack Overflow有很多关于此错误的问题。每个人都有其背景。我曾尝试应用大多数建议的解决方案,但都没有工作。我也是新来KOA和猫鼬错误:在使用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) { 

这意味着猫鼬保存功能发送头给用户。 如何解决这个问题?

回答

1

newPerson.save()是一个异步功能。将保存操作完成时调用的回调函数传递给它。然而,当它被调用时,你的路由器功能已经返回,所以已经发送的头文件。

这就是异步/等待模式进场的地方。由于您已经在异步功能中,所以您只需要等待.save()的结果。你可以等待承诺。幸运的是,如果你没有传递回调,mongoose .save()会返回一个承诺。这意味着你可以等待它。所以......使用异步时

await newPerson.save() 
ctx.render('show_message', { 
    message: "New person added", type: "success", person: personInfo 
}) 

错误处理做了一些不同的等待,或更好的错误处理再次得当;-)。

您将使用try/catch来进行错误处理,正如您在js中通常那样。

try{ 
    await newPerson.save() 
    ctx.render(...) 
}catch(err){ 
    ctx.status=500 
    ctx.body="somthing went wrong" 
} 
+0

It Worked !!非常感谢Will。你是一个救世主。我几乎放弃了猫鼬,直接与Mongodb打交道...... –

相关问题