Async.waterfall bind context

I am currently working on a web application with node.js and I cannot understand the context issue with the async library.

Here is the sample code for 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 will change it. I understood. But I don’t understand why this.saveNotificationForUsers code does not work like this:

 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 can show me the variable "this.doodle_id", which means that the function knows the context of "this". But the functions inside the waterfall call do not work, even if I bind 'this' to them.

I figured out a way to do this by creating a variable "me" that is equal to 'this' juste before I name the waterfall, and associating functions with the variable "me", not this, but I would like to understand why I have to do this, when i use async.waterfall, not when i use async.parallel.

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

+5
source share
1 answer

The problem you see has nothing to do with a parallel or a waterfall, but rather, as in the case of waterfall , referring to this in the notification.db.execute callback, whereas in the parallel case there is only a done call there. You can use bind again to bind this callback:

 async.waterfall([ function _getDoodleUsers (finish) { //… notification.db.execute(query, [ this.doodle_id ], { prepare : true }, function (err, result){ //… }.bind(this)); // <- this line }.bind(this) ], function (err) { //… }); 
+2
source

All Articles