2012-07-11 79 views
9

我已經編寫了一個節點腳本,通過請求REST API數據(使用庫請求)獲取一些數據。它包括像這樣幾個功能:如何解決'this'問題,如異步和請求

var data = { /* object to store all data */ }, 
function getKloutData() { 
    request(url, function() { /* store data */} 
} 
// and a function for twitter data 

因爲我想取後做一些東西,所有我使用的庫異步運行所有抓取功能,像這樣:

async.parallel([ getTwitterData, getKloutData ], function() { 
    console.log('done'); 
}); 

這一切工作正常,但是我希望把一切對象模式裏面,所以我可以在同一時間內獲取多個帳戶:

function Fetcher(name) { 
    this.userID = '' 
    this.user = { /* data */ } 
    this.init(); 
} 
Fetcher.prototype.init = function() { 
    async.parallel([ this.getTwitterData, this.getKloutData ], function() { 
     console.log('done'); 
    }); 
} 
Fetcher.prototype.getKloutData = function(callback) { 
    request(url, function() { /* store data */ }); 
}; 

這並不因爲異步工作,要求改變這種上下文。我可以繞過它的唯一途徑是通過異步和要求結合我的一切傳:

Fetcher.prototype.init = function() { 
    async.parallel([ this.getTwitterData.bind(this), this.getKloutData.bind(this) ], function() { 
     console.log('done'); 
    }); 
} 
Fetcher.prototype.getKloutData = function(callback) { 
    function saveData() { 
     /* store data */ 
    } 


    request(url, saveData.bind(this); 
}; 

我做得不對基本的東西?我認爲恢復到腳本並將其分叉到child_processes會產生很多開銷。

回答

9

你這樣做是完全正確的。

另一種方法是在上下文中始終保持,而不是使用bind對象的引用,但是這需要一些體操:

Fetcher.prototype.init = function() { 
    var self = this; 
    async.parallel([ 
     function(){ return self.getTwitterData() }, 
     function(){ return self.getKloutData() } 
    ], function() { 
     console.log('done'); 
    }); 
} 

Fetcher.prototype.getKloutData = function(callback) { 
    var self = this; 

    function saveData() { 
     // store data 
     self.blah(); 
    } 

    request(url, saveData); 
}; 

你也可以做的事先綁定:

Fetcher.prototype.bindAll = function(){ 
    this.getKloutData = this.prototype.getKloutData.bind(this); 
    this.getTwitterData = this.prototype.getTwitterData.bind(this); 
}; 

Fetcher.prototype.init = function(){ 
    this.bindAll(); 
    async.parallel([ this.getTwitterData, this.getKloutData ], function() { 
     console.log('done'); 
    }); 
}; 
+3

下劃線庫有一個名爲'bindAll'一個方便的功能,使這個痛苦少。如果您選擇使用CoffeeScript,則可以使用胖箭頭定義方法,而不必進行任何顯式綁定。 – 2012-07-11 09:05:22

3

您可以保存此爲另一個變量:

var me = this; 

然後me是你this

0

使用此功能實例化對象:

function newClass(klass) { 
    var obj = new klass; 

    $.map(obj, function(value, key) { 
     if (typeof value == "function") { 
      obj[key] = value.bind(obj); 
     } 
    }); 

    return obj; 
} 

這樣做會au所有函數都會自動綁定,所以當對象中的方法具有對象的上下文時,您將獲得習慣的OOP風格的對象 。

所以你實例化對象,你不通過:

var obj = new Fetcher(); 

但是:

var obj = newClass(Fetcher); 
+0

我原來的問題是在jQuery沒有意義的nodejs環境中。同樣,下劃線和lodash(在所有JS環境中工作的庫)中的bindAll方法都是爲您設計的。 – askmike 2014-12-07 14:20:00