2012-07-11 6 views
9

(ライブラリリクエストを使用して)REST APIデータを要求することによってデータを取得するノードスクリプトを作成しました。私はいくつかのものをしたいので、私はそうのようなすべてのフェッチ機能を実行するために、ライブラリ非同期を使用するすべてのフェッチ後非同期やリクエストなどのノードライブラリの問題を解決する方法

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を選択した場合は、太い矢印でメソッドを定義するだけで、明示的にバインディングする必要はありません。 –

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環境で動作するlibs)の 'bindAll'メソッドは、これを行うために設計されています。 – askmike

関連する問題