Oro*_*dan 5 javascript asynchronous bind node.js
我目前正在使用node.js处理Web应用程序,我无法解决库异步的上下文问题.
这是我的应用程序的代码示例:
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);
});
};
Run Code Online (Sandbox Code Playgroud)
所以在这段代码中,我必须使用bind方法绑定我的对象的上下文(this),否则异步更改它.我知道了.但我不明白为什么this.saveNotificationForUsers的代码不能以相同的方式工作:
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);
});
};
Run Code Online (Sandbox Code Playgroud)
当我调用前面的代码时,第一个console.log能够显示"this.doodle_id"变量,这意味着该函数知道"this"上下文.但是瀑布调用中的函数没有,即使我将'this'绑定到它们.
我想通过在调用瀑布之前创建一个等于'this'juste的'me'变量,并通过将函数与'me'变量绑定'来实现它的工作方式,而不是这个,但我想了解为什么我在使用async.waterfall时被迫这样做,而不是在我使用async.parallel时.
我希望我能清楚地描述我的问题,如果有人能帮助我理解这将是一件非常愉快的事情!
您\xe2\x80\x99re 看到的问题与并行或瀑布无关,而是在这种情况下waterfall,您\xe2\x80\x99rethis在回调中引用notification.db.execute,而在这种parallel情况下,仅调用done在那里。你可以使用bind也可以再次使用来绑定该回调:
async.waterfall([\n function _getDoodleUsers (finish) {\n //\xe2\x80\xa6\n notification.db.execute(query, [ this.doodle_id ], { prepare : true }, function (err, result){\n //\xe2\x80\xa6\n }.bind(this)); // <- this line\n }.bind(this)\n], function (err) {\n //\xe2\x80\xa6\n});\nRun Code Online (Sandbox Code Playgroud)\n