问题
I am getting inconsistent results from my server. Sometimes the right response is sent and sometimes I get the error
Can't remove headers after they are sent
Using Node.js, Koa.js, and Mongoose
router
.get('/events/', function* getEvent() {
let eventList = [];
yield Event.find({}, (error, events) => {
if (error) {
this.response.body = 'Unable to get events.';
this.status = 404;
return;
}
eventList = events;
eventList.sort((first, second) => {
// sort implementation
});
this.response.body = eventList;
this.status = 200;
});
});
回答1:
The issue is caused by your callback which introduces a race condition since your yield isn't waiting for it to finish. In Koa v1.x, you generally only use a callback API to return a promise.
Here's how you'd write your example with Koa v1.x:
router
.get('/events', function * () {
let events
try {
events = yield Event.find({})
} catch (err) {
this.status = 503
this.body = 'Unable to get events'
return
}
events = sort(events)
this.body = events // Implicit 200 response
})
Event.find
just needs to return something yieldable like a promise. Check to see if the library your using has a promise-returning version.
Though normally you'd just write it like this:
router
.get('/events', function * () {
let events = yield Event.find({})
events = sort(events)
this.body = events
})
Since it's an internal error (500 response) if Event.find
is down. Koa will turn uncaught errors into 500 responses.
回答2:
Basically, after you set this.status
to 200, it throws an error because this.response.body is probably undefined.
Go ahead and console.log()
this.response.body and see if it is defined. If it is undefined
, I would guess req.body
is not being populated correctly OR it is an asynchronous node problem. Basically, eventList.sort() is asynchronously executing as this.response.body = eventList is set. Thus eventList is not sorted yet when you set it. To fix this put it inside eventList.sort() callback.
EDIT: after seeing your comment, I am pretty sure it is asynchronous problem now. Let me know if putting the last two lines inside the sort call works out for you.
来源:https://stackoverflow.com/questions/38450258/cant-remove-headers-after-they-are-sent