2017-01-07 17 views
1

ノードを非同期的な知識なしに開始し、データをコールバックの一部として配列にプッシュする方法が不思議です。出力配列は宣言されていますが、要求コールバック内で参照されているときは未定義です。その変数をコールバック関数のスコープに渡すだけの簡単な方法はありますか?nodejsが要求のあるforループ内に配列をプッシュ

理想的には、呼び出し元に返された各リクエストの結果の配列を返信したいと考えています。

const request = require('request'); 

module.exports = { 

apiRatingCall: function (input, callback) { 

var output = [] 

    for (var i = 0; i < input.length; i++) { 
    var options = { 
    url: 'someAPIURL' + '?longitude=' + input[i].longitude + '&latitude=' + input[i].latitude + '&name=' + input[i].name, 
    headers: { 
     'x-api-version': 2 
    } 
    }; 

    request(options, function (error, response, body) { 
    if (!error && response.statusCode == 200) { 

     var info = JSON.parse(body) 
     output.push(info) // this is not working as ouput is undefined at this point 
    } 
    }) 
    } 
    callback(output) 
    } 
} 

おかげ

答えて

0

私の答えは、私は

を約束し、この問題のための唯一の方法で実行することができます
module.exports = { 

apiRatingCall: function (input, callback) { 

var output = [] 

for (var i = 0; i < input.length; i++) { 
var options = { 
    url: 'someAPIURL' + '?longitude=' + input[i].longitude + '&latitude=' + input[i].latitude + '&name=' + input[i].name, 
headers: { 
    'x-api-version': 2 
} 
}; 

request(options, function (error, response, body) { 
    if (!error && response.statusCode == 200) { 

    var info = JSON.parse(body) 
    output.push(info) // this is not working as ouput is undefined at this point 
    } 
}) 
} 
setTimeout(function(){ 
    callback(output) 
},500) 

} 
} 
+0

ネットワーク接続が十分に速くなく、すべての応答が500ミル戻ってこない場合は、どうしますか? –

0

あなたはforループの終了を確認し、それによって、プログラミングに多分非常に規範的ではなく、あなたのcallback

var loopCallback = function(error, response, body) { 
    if (!error && response.statusCode == 200) { 
    var info = JSON.parse(body) 
    output.push(info) 
    } 
    if(i == input.length - 1){ //checking index for completion of loop 
    callback(output); 
    } 
} 

request(options, loopCallback}) 
+1

Ajaxリクエストは、通常、発行されたのと同じ順番で回答を得ません。最後のコールバックをコールバックすることは、他のコールが終了したことを保証することではありません。 – 4castle

+0

素晴らしいですが、出力変数がまだヌルで、データがプッシュされませんでした。要求コールバック内の配列にプッシュする方法はありますか? –

+0

@ 4castleありがとうございます。適切な解決策が得られるまで、これを回避策と見なすことができます。 –

0

asyncモジュールを見てください。 bluebirdと約束を使用したくない場合は、配列とコレクションを使って非同期操作を行うのが良いモジュールです。

npm install async -Sを実行します。

const request = require('request'); 
const async = require('async); 

module.exports = { 

    apiRatingCall: function (inputs, callback) { 

    var output = [] 


    async.each(inputs, function(input, cb) { 
     var options = { 
     url: 'someAPIURL' + '?longitude=' + input.longitude + '&latitude=' + input.latitude + '&name=' + input.name, 
     headers: { 
     'x-api-version': 2 
     } 
     request(options, function (error, response, body) { 
     if (!error && response.statusCode == 200) { 

      var info = JSON.parse(body) 
      output.push(info); 
      cb(); 
     }else{ 
      //if any of the request fails then return error 
      cb(error); 
     } 
    }) 

    }, function(err){ 
     if(!err){ 
     return callback(output); 
     }else{ 
     //if any of the request return error 
     return callback(err); 
     } 
    }); 
} 
関連する問題