lundi 20 avril 2015

async.waterfall bind context

I am currently working on a web application with node.js and I can't figure a context problem with the library async.

Here is a example of code of my application :

notification.prototype.save = function (callback) {

    async.parallel([
        // Save the notification and associate it with the doodle
        function _saveNotification (done) {

            var query = 'INSERT INTO notification (notification_id, user_id, doodle_id, schedule_id) values (?, ?, ?, ?)';
            notification.db.execute(query, [ this.notification_id, this.user_id, this.doodle_id, this.schedule_id ], { prepare : true }, function (err) {
                return done(err);
            });

            console.log("SAVE NOTIFICATION");
            console.log("doodle_id", this.doodle_id);

        }.bind(this),

        // Save notification for the users with the good profile configuration
        function _saveNotificationForUsers (done) {
            this.saveNotificationForUsers(done);
        }.bind(this)

    ], function (err) {
        return callback(err);
    });
};

So in this code, I have to use the bind method to bind the context of my object ( this ) because otherwise async change it. I got it. But what I don't understand is why the code of this.saveNotificationForUsers does not work the same way :

notification.prototype.saveNotificationForUsers = function (callback) {

    console.log("SAVE NOTIFICATION FOR USERS");
    console.log("doodle id : ", this.doodle_id);

    async.waterfall([
        // Get the users of the doodle
        function _getDoodleUsers (finish) {
            var query = 'SELECT user_id FROM users_by_doodle WHERE doodle_id = ?';
            notification.db.execute(query, [ this.doodle_id ], { prepare : true }, function (err, result){
                if (err || result.rows.length === 0) {
                    return finish(err);
                }

                console.log("GET DOODLE USERS");
                console.log("doodle id : ", this.doodle_id);

                return finish(err, result.rows);
            });
        }.bind(this)
    ], function (err) {
        return callback(err);
    });
};

When I call the previous code, the first console.log is able to show me the "this.doodle_id" variable, which means the function knows the "this" context. But the functions inside the waterfall call does not, even if I bind 'this' to them.

I figured a way to make it works by creating a 'me' variable which is equal to 'this' juste before I call waterfall, and by binding the functions with the 'me' variable' and not this, but I would like to understand why I am forced to do this when I use async.waterfall and not when I use async.parallel.

I hope I was clear with the description of my problem, if someone can help me understand it will be a great pleasure !

Aucun commentaire:

Enregistrer un commentaire