2015-12-23 169 views
6

我想在單個URL調用中調用多個URL,並將其推送到數組中的json響應,併發送該數組以響應最終用戶。在Node.js中的單個HTTP請求中調用多個HTTP請求

我的代碼看起來像這樣:

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); 
}); 

我也嘗試過這種使用NPM請求模塊。 當我運行這段代碼時,它只返回NULL或一些只有頭文件的隨機輸出。

我的目標是在單個節點獲取請求中調用多個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個參數,第一個是數組,第二個是您希望與該數組的每個元素調用的迭代器函數,以及在async.map處理完成時調用的回調函數。

map(arr, iterator, [callback])

通過 迭代函數映射在ARR每個值的值的一個新的數組。使用來自arr 的項目和完成處理時的回調來調用迭代器。這些 回調中的每一個都有兩個參數:一個錯誤,以及來自 arr的轉換項。如果迭代器將錯誤傳遞給它的回調函數,則主回調函數 (對於map函數)會立即調用該錯誤。

注意:所有對迭代函數的調用都是並行的。

在你的httpGet函數中,你調用request函數傳遞的url,並明確地告訴響應格式爲jsonrequest,完成處理後,用三個參數調用回調函數,err - 如果有的話,res - 服務器響應,body - 響應體。 如果request沒有errasync.map將這些回調的結果作爲一個數組收集,並在最後將該數組傳遞給它的第三個回調函數。否則,如果(err)爲真,則async.map函數將停止執行並使用err調用其回調函數。

+0

這裏有什麼'請求'? 'async'怎麼樣?在答案中使用庫是好的,但只有當你指定你正在使用的庫時:P – birdoftheday

+0

好吧,似乎已經知道這些包。無論如何,更新爲其他用戶。 – yoogeeks

+0

謝謝,它的工作原理。尋找一些發電機類的東西。 –

4

我建議使用async庫。

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

的片段上方將執行http.get呼籲每個並行的網址,並收到所有的響應後,將調用回調函數的所有調用的結果。

如果您想要連續調用網址,則可以使用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