2015-04-20 45 views
5

我目前正在研究一個帶有node.js的web應用程序,並且我無法確定庫異步的上下文問題。async.waterfall綁定上下文

這裏是我的應用程序的代碼,例如:

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); 
    }); 
}; 

所以在這個代碼,我必須使用綁定方法綁定我的對象(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); 
    }); 
}; 

當我調用上面的代碼中,第一個執行console.log能告訴我「這.doodle_id「變量,這意味着該函數知道」this「上下文。 但是瀑布調用中的函數不會,即使我將「this」綁定到它們。

我想通過在我調用瀑布之前創建一個'me'變量,使其等於'this'變量,並將函數與'me'變量'綁定在一起,而不是這個,但我想了解爲什麼當我使用async.waterfall而不是當我使用async.parallel時,我不得不這樣做。

我希望我對我的問題的描述很清楚,如果有人能夠幫助我理解這將是一種樂趣!

回答

2

你看到這個問題已經什麼都沒有做平行或瀑布而是如何在waterfall情況下,你在回調引用thisnotification.db.execute,而在parallel情況下,只有一個呼叫那裏有done。您可以再次使用bind來綁定該回調以及:

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) { 
    //… 
}); 
+0

哦,這是真的!我不知道將「this」綁定到查詢的回調函數可能會使其工作,因爲參數this.doodle_id未定義。非常感謝你我現在意識到這一點:D – Orodan

+1

我只是好奇。難道你不能在最上面聲明'var self = this;'並且在回調中使用它,而不是嵌套的'bind(this)',這很難讀和容易出錯?只需用'self'代替所有'this'。只是看着這個,我可能會錯過一些東西。 –

+0

@KevinGhaboosi當然,這是一個有效的方法來做到這一點(雙關語意圖)以及。 –