我的网站上有一页从https://hotelspro.com
获取航班详情输入航班详细信息后,我收到了大约400条不同的记录。问题是我必须在每条记录中循环,并发送单独的API请求以获取酒店信息。
我只能使用PHP或JavaScript。
使用PHP,它就像永远一样。我尝试了几种解决方案:
PHP - 解决方案1:使用curl_exec()
$count = xxx; //Where xxx is the number of hotels
for ($i = 0; $i < $count; $i++) {
$hotelCode = $json["results"][$i]["hotel_code"];
$url = "http://cosmos.metglobal.tech/api/static/v1/hotels/" . $hotelCode . "/" ;
$username = 'xxx';
$password = 'xxx';
$auth = base64_encode("$username:$password");
$curl = curl_init();
$data = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"authorization: Basic $auth",
"cache-control: no-cache",
'Content-Length: 0'
),
);
curl_setopt_array($curl, $data);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
$json = json_decode($response, true);
}
PHP - 解决方案2:使用curl_multi_exec()
以下代码是从Stack Overflow
上的答案中复制的$urls = array() ;
for ($i = 0; $i < $count; $i++) {
$urls[] = "http://cosmos.metglobal.tech/api/static/v1/hotels/" . $json["results"][$i]["hotel_code"] . "/" ;
}
/* ********** Start Multi Threading ********** */
$active = 0 ;
// cURL multi-handle
$mh = curl_multi_init();
// This will hold cURLS requests for each file
$requests = array();
$options = array(
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_AUTOREFERER => true,
CURLOPT_HTTPHEADER => array("Content-Type: application/json"),
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERPWD => "xxx:xxx"
);
foreach ($urls as $key => $url) {
// Add initialized cURL object to array
$requests[$key] = curl_init($url);
// Set cURL object options
curl_setopt_array($requests[$key], $options);
// Add cURL object to multi-handle
curl_multi_add_handle($mh, $requests[$key]);
$active++;
}
// Do while all request have been completed
do {
curl_multi_exec($mh, $active);
} while ($active > 0);
// Collect all data here and clean up
$j = 0 ;
foreach ($requests as $key => $request) {
$result = curl_multi_getcontent($request); // Use this if you're not downloading into file, also remove CURLOPT_FILE option and fstreams array
curl_multi_remove_handle($mh, $request); //assuming we're being responsible about our resource management
curl_close($request); //being responsible again. THIS MUST GO AFTER curl_multi_getcontent();
$json["results"][$j]["hotel_details"] = json_decode($result, true) ;
$j++ ;
}
curl_multi_close($mh);
/* ********** End Multi Threading ********** */
两个PHP解决方案需要花费大约1分钟来遍历所有记录。所以我现在正在尝试使用JavaScript同步请求发送请求。
JavaScript - 解决方案1:
for (var i = 0; i < maxCount; i++) {
var thisHotel = extJson.hotels.results[i] ;
var hotelCode = thisHotel.hotel_code;
$.get("/travel/hotel_pro_details/" + thisHotel.hotel_code, function (json) { // /travel/hotel_pro_details/ is a function on my website that calls HotelsPro API
//Code Handling Here
}
}
上面的JavaScript解决方案也花了很多时间,但其中的好处是我可以在从API中获取结果后依次追加结果。
但我正在寻找一种更好的解决方案来减少加载时间。 由于我在JavaScript中循环记录,因此我无法立即发送所有记录并等待结果。
所以我的问题是:
有没有办法使用JavaScript,我可以在一个AJAX调用中发送多个记录,然后逐个处理所有回复?
答案 0 :(得分:1)
如果您准备使用外部库,我猜您可以考虑使用rxjs及其Observable
模式,您可以使用他们的forkJoin
方法发送所有{{3}}模式1}}同时请求:
$get
<小时/> 的演示:强>
Rx.Observable.forkJoin(array)
.subscribe(function(data) {
/* data for all requests available here */
}
$(document).ready(function() {
// use your for loop to push() your requests into an array
var array = [
$.get('https://api.chucknorris.io/jokes/random'),
$.get('https://api.chucknorris.io/jokes/random'),
$.get('https://api.chucknorris.io/jokes/random'),
$.get('https://api.chucknorris.io/jokes/random')
];
// make all the http request at the same time
Rx.Observable.forkJoin(array)
.subscribe(function(data) {
// Handle the response for each request individually
$('body').append(data[0].value + '<br><hr>');
$('body').append(data[1].value + '<br><hr>');
$('body').append(data[2].value + '<br><hr>');
$('body').append(data[3].value + '<br>');
})
});