42

ノードで単純なフィード リーダーを作成しようとしていますが、node.js での複数のリクエストに関する問題に直面しています。たとえば、次のような URL を持つテーブルを取得しました。

urls = [
"http://url1.com/rss.xml",
"http://url2.com",
"http://url3.com"];

次に、各 URL のコンテンツを取得します。最初for(var i in urls)のアイデアは使用することでしたが、それは良い考えではありません。最良の選択肢は非同期で行うことですが、その方法がわかりません。

何か案は?

編集:

私はこのコードを得ました:

var data = [];
for(var i = 0; i<urls.length; i++){
    http.get(urls[i], function(response){
    console.log('Reponse: ', response.statusCode, ' from url: ', urls[i]);
    var body = '';
    response.on('data', function(chunk){
        body += chunk;
    });

    response.on('end', function() {
        data.push(body);
    });
}).on('error', function(e){
    console.log('Error: ', e.message);
});
}

問題は、最初にループ内の各要素に対して行 "http.get..." が呼び出され、その後にイベント response.on('data') が呼び出され、その後に response.on('end') が呼び出されることです。それは混乱を引き起こし、私はこれを処理する方法がわかりません。

4

6 に答える 6

53

これは古い質問だと思いますが、より良い解決策は JavaScript を使用することだと思いますPromise.all():

const request = require('request-promise');
const urls = ["http://www.google.com", "http://www.example.com"];
const promises = urls.map(url => request(url));
Promise.all(promises).then((data) => {
    // data = [promise1,promise2]
});
于 2017-03-11T21:52:43.027 に答える
45

デフォルトでは、ノードhttpリクエストは非同期です。コード内でそれらを順番に開始し、すべてのリクエストが完了したときに開始される関数を呼び出すことができます。手動で行う (終了したリクエストと開始したリクエストをカウントする) か、async.js を使用することができます。

これは依存しない方法です (エラーチェックは省略されます):

var http = require('http');    
var urls = ["http://www.google.com", "http://www.example.com"];
var responses = [];
var completed_requests = 0;

for (i in urls) {
    http.get(urls[i], function(res) {
        responses.push(res);
        completed_requests++;
        if (completed_requests == urls.length) {
            // All download done, process responses array
            console.log(responses);
        }
    });
}
于 2013-11-11T16:51:07.697 に答える
27

(データ完了イベント)が正確な数のリクエストと呼ばれていることを確認する必要がendあります...これは実際の例です:

var http = require('http');
var urls = ['http://adrianmejia.com/atom.xml', 'http://twitrss.me/twitter_user_to_rss/?user=amejiarosario'];
var completed_requests = 0;

urls.forEach(function(url) {
  var responses = [];
  http.get(url, function(res) {
    res.on('data', function(chunk){
      responses.push(chunk);
    });

    res.on('end', function(){
      if (completed_requests++ == urls.length - 1) {
        // All downloads are completed
        console.log('body:', responses.join());
      }      
    });
  });
})
于 2014-10-08T10:43:39.813 に答える