[英]Javascript - XMLHttpRequest how to send multiple simultaneous requests?
我遇到一個非常自然的問題。 我正在嘗試實現一個購物車,借此在客戶端存儲了Cookie,以識別已訂購哪些商品的ID及其數量。 當我加載結帳HTML頁面時,我正在讀取cookie並一個接一個地獲取商品ID。 然后對於每個項目ID,我都會將請求發送到我的servlet,該servlet將返回信息。 為了簡化操作,我將多余的行截斷了:
var arrXhr = new Array();
function ProcessCheckout(){
try
{
var myArr = new Array();
myArr[0]=84234;
myArr[1]=84239;
myArr[2]=84240;
for (var intLoop=0; intLoop < myArr.length; intLoop++){
var intIcint=myArr[intLoop];
arrXhr[intIcint]= new XMLHttpRequest();
function Populate_CheckOutCart(){
arrXhr[intIcint].open('POST', strRemoteUriReq, true);
arrXhr[intIcint].send(null);
arrXhr[intIcint].onreadystatechange= ProcessSrvRsp(intIcint);
}
}catch(errors)
{
alert(errors.message);
}
}
}
function ProcessSrvRsp(ItemToProcess){
if (arrXhr[ItemToProcess].readyState==4){
//doing some functionality here on item code: ItemToProcess
}
}
問題在這里
arrXhr[intIcint].open('POST', strRemoteUriReq, true);
如果我將請求類型更改為SYNCHRONOUS通信,即從TRUE更改為FALSE,則一切正常,但是如您所知,網頁將必須等待服務器處理每個項目。 因此,網頁將發送對項目84234的請求,等待,當有響應時,然后發送對項目84239的請求,等等。
據我所知,如果我改回ASYNCHRONOUS XMLHttpRequest,除了/僅當arrXhr [ItemToProcess] .readyState == 1時,什么都不會發生。 但是對於其他2、3、4(其中4個是最重要的州)而言,它們永遠不會被觸發。
知道為什么嗎? 最重要的是,我們如何克服這個問題? 我知道XMLHttpRequest在單獨的線程上工作,這很可能是問題所在,但我找不到解決方案。
我的目標很簡單,我希望我的網頁在從磁盤上的cookie讀取后立即將多個請求同時發送到我的servlet。 因此,對於每個Cookie,我想發送請求並希望以異步方式接收響應。 我不希望瀏覽器在最終請求完成之前一直等待。 因此,如果您有任何其他想法/實現,我可以是一個非常開放的人;)
ps我正在使用TomCat 7
如下所示:
function ProcessCheckout() {
var arrXhr=[];
var myArr=[];
myArr.push(84234);
myArr.push(84239);
myArr.push(84240);
var helperFunc=function(arrIndex,itemId) {
return function() {
if(arrXhr[arrIndex].readyState===4) {
//doing some functionality here on item
ProcessResponseForItem(arrIndex,myArr,arrXhr);
// doing some code if all xhr's is completed
ProcessResponseForAllItems(myArr,arrXhr);
}
}
}
for(var i=0; i<myArr.length; i++) {
var itemId=myArr[i];
arrXhr[i]=new XMLHttpRequest();
arrXhr[i].open('POST', strRemoteUriReq, true);
arrXhr[i].onreadystatechange=helperFunc(i,itemId);
arrXhr[i].send(/*some item data sended to server for item with id itemId*/);
}
}
function ProcessResponseForItem(arrIndex,myArr,arrXhr) {
if(arrXhr[arrIndex].status===200) {
// do some code if response is succ
}
else {
// if fail
}
}
function ProcessResponseForAllItems(myArr,arrXhr) {
var i,isAllComplete=true,isAllCompleteSucc=true;
for(i=0;i<myArr.length;i++) if((!arrXhr[i])||(arrXhr[i].readyState!==4)) {
isAllComplete=false;
break;
}
if(isAllComplete) {
for(i=0;i<myArr.length;i++) if(arrXhr[i].readyState!==200) {
isAllCompleteSucc=false;
break;
}
if(isAllCompleteSucc) {
// do some code when all is completed and all is succ
}
else {
// do some code when all is completed and some is fail
}
}
}
您必須使用“ this”代替arrXhr [intIcint]
var arrXhr = new Array();
function ProcessCheckout(){
try
{
var myArr = new Array();
myArr[0]=84234;
myArr[1]=84239;
myArr[2]=84240;
for (var intLoop=0; intLoop < myArr.length; intLoop++){
var intIcint=myArr[intLoop];
xhr= new XMLHttpRequest();
function Populate_CheckOutCart(){
xhr.open('POST', strRemoteUriReq, true);
xhr.send(null);
xhr.onreadystatechange= ProcessSrvRsp();
// or xhr.addEventListener("load", ProcessSrvRsp);
}
}catch(errors)
{
alert(errors.message);
}
}
}
function ProcessSrvRsp(){
if (this.readyState==4){
//doing some functionality here on item code: this
}
}
我強烈建議您使用事件監聽器,以防您願意使用異步處理。
請注意,由於對用戶體驗的負面影響,Gecko 30.0(Firefox 30.0等)不贊成使用同步請求。
這個(理解事件監聽器)當然是異步的,並在響應到達時立即對其進行處理。
到目前為止,就緒狀態更改可能會帶來很多並發症和頭痛。 當您要處理多個響應並且響應處理的順序很重要時,尤其如此。
當您要在響應到達時對其進行處理時,有一種簡單的方法可以將EventListener添加到每個請求中。
arrXhr[intIcint].open('POST', strRemoteUriReq, true);
arrXhr[intIcint].addEventListener("load", processResponse);
arrXhr[intIcint].send(null);
...
function processResponse() {
console.log("Response arrived.");
}
...您甚至可以自定義要處理的狀態。 這些是當前允許的響應狀態:
arrXhr[intIcint].addEventListener("progress", updateProgress);
arrXhr[intIcint].addEventListener("load", transferComplete);
arrXhr[intIcint].addEventListener("error", transferFailed);
arrXhr[intIcint].addEventListener("abort", transferCanceled);
不必為每個產品ID發送多個同時請求,而是將所有ID包裝到一個數組中,進行序列化並僅使用一個請求。
var ids = [1, 2, 3];
var serializedIds = ids.join('|'); // serializedIds = '1|2|3';
通過請求僅發送serializedIds變量
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.