Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make synchronous call with mongoose and nodejs

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?

like image 631
duckegg Avatar asked Jul 02 '14 16:07

duckegg


People also ask

Is Mongoose connect synchronous?

Mongoose provides built-in and custom validators, and synchronous and asynchronous validators.

Can NodeJS be synchronous?

NodeJS is an asynchronous event-driven JavaScript runtime environment designed to build scalable network applications. Asynchronous here refers to all those functions in JavaScript that are processed in the background without blocking any other request.

Should I use async await with Mongoose?

You are most likely to accidentally re-execute queries in this way when mixing callbacks with async/await. This is never necessary and should be avoided. If you need a Query to return a fully-fledged promise instead of a thenable, you can use Query#exec().


1 Answers

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.

like image 53
danday74 Avatar answered Nov 15 '22 07:11

danday74