2015-12-23 15 views
6

私は、単一のURL呼び出しで複数のURLを呼び出し、それをjson応答で配列にプッシュし、その配列をエンドユーザーに応答して送信しようとしています。このようなNode.jsの単一のHTTPリクエストで複数のHTTPリクエストを呼び出す

私のコードを見て:私も、この使用してNPM要求モジュールを試してみました

var express = require('express'); 

var main_router = express.Router(); 

var http = require('http'); 

urls = [ 
"http://localhost:3010/alm/build_tool", 
"http://localhost:3010/alm/development_tool", 
"http://localhost:3010/alm/project_architecture"]; 

var responses = []; 

main_router.route('/') 

.get(function (req, res) { 

var completed_requests = 0; 

for (url in urls) { 

    http.get(url, function(res) { 

    responses.push(res.body); 

    completed_request++; 

    if (completed_request == urls.length) { 

     // All download done, process responses array 
    } 
    }); 
} 
res.send(responses); 
}); 

。 このコードを実行すると、ヘッダーのみを持つNULLまたは一部のランダム出力が返されます。

私の目的は、単一ノードのget要求で複数のURLを呼び出して、配列にJSON出力を追加してエンドユーザーに送信することです。

おかげ

+0

コールバックを使用する必要があります。または、非同期モジュールhttps://github.com/caolan/asyncを提案することができます –

+0

[回答](http://stackoverflow.com/a/26254973/973680)を参照してください。 'res.on( 'end'、function ...' –

答えて

14

、説明

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

function httpGet(url, callback) { 
    const options = { 
    url : url, 
    json : true 
    }; 
    request(options, 
    function(err, res, body) { 
     callback(err, body); 
    } 
); 
} 

const urls= [ 
    "http://localhost:3010/alm/build_tool", 
    "http://localhost:3010/alm/development_tool", 
    "http://localhost:3010/alm/project_architecture" 
]; 

async.map(urls, httpGet, function (err, res){ 
    if (err) return console.log(err); 
    console.log(res); 
}); 

、このコードを試してみてください。 このコードは、asyncrequestノードパッケージを使用しています。 async.mapは3つのパラメータを取ります。最初は配列、2番目はその配列の各要素で呼び出すイテレータ関数、async.mapが処理を終了したときに呼び出されるコールバック関数です。

map(arr, iterator, [callback])

イテレータ関数を介してARRの各値をマッピングすることによって値の新しい配列を生成。イテレータは、arr の項目と、処理が終了したときのコールバックで呼び出されます。これらの各 コールバックは2つの引数をとります:エラー、変換された項目は からです。イテレータがコールバックにエラーを渡すと、メインコールバック (マップ関数用)がすぐにエラーとともに呼び出されます。

注:イテレータ関数の呼び出しはすべて並列です。

httpGet関数の内部では、URLを指定して関数を呼び出し、応答形式を明示的にjsonと指定しています。 requestは、処理が終了すると、3つのパラメータ、エラーがあれば、サーバレスポンス、ボディレスポンスボディでコールバック関数を呼び出します。 requestからerrがない場合、async.mapは、これらのコールバックの結果を配列として収集し、その最後の配列を3番目のコールバック関数に渡します。それ以外の場合、(err)が真の場合、async.map関数は実行を停止し、errでコールバックを呼び出します。

+0

ここに '要求'は何ですか?どのように '非同期'について?答えにライブラリを使用するのは問題ありませんが、使用しているライブラリを指定した場合に限ります:P – birdoftheday

+0

質問者はすでにこれらのパッケージを認識しているようです。とにかく、他のユーザーの更新。 – yoogeeks

+0

ありがとう、それは動作します。いくつかの発電機の種類のものを探しています。 –

4

私はasyncライブラリを使用することをお勧めします。

async.map(urls, http.get, function(err, responses){ 
    if (err){ 
    // handle error 
    } 
    else { 
    res.send responses 
    } 
}) 

スニペットは、上記並列内のURLのそれぞれについて、http.get呼び出しを実行し、すべての応答が受信された後の呼び出しのすべての結果を使用してコールバック関数を呼び出します。

URLを連続して呼び出す場合は、代わりにasync.mapSeriesを使用できます。同時リクエスト数を制限する場合は、async.mapLimitを使用できます。ここで

+0

コメントをお寄せいただきありがとうございます。利用可能なコードがあれば、共有してください。応答では何も得られません。main_router.route( '/') .get(function(req、res)){ var test = async.each(urls、http.get、function(err、responses、callback){ もしそうでなければ(ERR){ //ハンドルエラー } { 戻り応答; }}) res.send(テスト); res.end(); }); –

+0

注: '非同期.each'コールバックは応答を処理しません。呼び出しの終わりに応答が必要な場合は、 'async.map'を使用してください。これは、コールバック関数の配列の形式で各HTTP要求の応答を持ちます。 – yoogeeks

+0

@yoogeeks正しいですか?私は自分の答えを更新しました。 – Ita

関連する問題