I'm designing a client/server synchronization feature. The client sends a bunch of changed events to server. The server will do creation, deletion or modification upon requested item status. After the database operation, the server need send a summary back to client.
Below is excerpt from my server side code, designed with mongoose and restify.
var EventModel = mongoose.model('Event', eventSchema);
server.post("/sync", function (req, res, next) {
var events = req.params.events;
var created = [], deleted = [], updated = [];
events.forEach(function (elem) {
if (elem.status == 0) {
// Delete
EventModel.remove({ _id: elem.uuid }, function (err, event) {
if (!err) deleted.push({uuid: elem.uuid});
});
} else if (elem.status == 1) {
// Create and update uuid
var event = new EventModel(elem);
event.save(function (err, doc) {
if (!err) {
elem.uuid = event._doc._id;
created.push(elem);
}
});
} else if (elem.status == 2) {
// Update
EventModel.findOne({ _id: elem.uuid }, function (err, event) {
event.save(function (err, doc) {
if (!err) updated.push({uuid:elem.uuid});
});
});
}
});
// Notify client what are processed.
// PROBLEM: created, deleted, updated are always empty!
res.send({processed: {created: created, deleted: deleted, updated: updated}});
});
Since mongoose do CRUD in async way, the response created
,deleted
and updated
are always empty.
Is there any way to let the mongoose operation in series?
As stated in the comments you could use the npm async module.
Alternatively, you may prefer to nest callbacks (but this might lead to what is known as callback hell, viz many nested callbacks) or take advantage of the mongoose .then() method - see http://mongoosejs.com/docs/promises.html
Here you can do ..
EventModel.remove(args).then((removeResponse) => {
return EventModel.findOne(args);
}).then((findResponse) => {
// etc
})
These requests will happen synchronously.