Javascript - XMLHttpRequest 如何同时发送多个请求?
我遇到了一个非常超自然的问题。我正在尝试实现一个购物车,其中我在客户端存储了 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);
如果我将请求类型更改为同步通信,即从 TRUE 更改为 FALSE,一切都会正常工作,但正如您所知,网页将不得不等待服务器处理每个项目。因此,网页将发送对项目 84234 的请求,等待,当有响应时,然后发送对项目 84239 的请求,等等。
据我所知,如果我改回异步 XMLHttpRequest,除了/仅当 arrXhr[ ItemToProcess].readyState==1。但至于其他状态 2、3、4(4 是开始工作时最重要的状态),它们永远不会被触发。
知道为什么吗?最重要的是我们如何克服这个问题?我知道 XMLHttpRequest 在单独的线程上工作,很可能这就是问题所在,但我无法找到解决方案。
我的目标很简单,我希望我的网页在从磁盘上的 cookie 读取时立即向我的 servlet 发送多个请求;因此,对于每个 cookie,我想发送一个请求并期望以异步方式接收响应。我不希望浏览器一直等待最终请求完成。所以,如果您有任何其他想法/实现,我可以是一个非常开放的人;)
ps我正在使用 TomCat 7
I'm encountering a very paranormal problem. I'm trying to implement a shopping cart, whereby I have cookies stored on the client side to identify which items' ID have been ordered and their quantities. When I load the checkout HTML page, I'm reading the cookies and getting the item id one after the other; then for each item id I ll be sending the request to my servlet which would return the information. I have truncated redundant lines to keep it simple to follow:
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
}
}
The problem here is in line
arrXhr[intIcint].open('POST', strRemoteUriReq, true);
If I change the request type to SYNCHRONOUS communication, i.e. from TRUE to FALSE, everything works correctly, but as you know the web page will have to wait for the server to process every item. Hence, the web page will send a request for item 84234, waits, when there is a response then sends a request for item 84239, etc..
From my knowledge, if I change back ASYNCHRONOUS XMLHttpRequest, nothing happens except/only when arrXhr[ItemToProcess].readyState==1. But as regards the other states, 2,3,4 (4 being the most important to start working with), they are never triggered.
Any idea why? And most importantly how can we overcome this? I'm aware that the XMLHttpRequest works on a separate thread and most probably this is the issue, but I can't figure out a solution.
My objective is simple, I want my web page to send multiple requests to my servlet simultaneously as soon as it is reading from the cookies on the disk; hence for each cookie I want to send a request and expect to receive a response in an asynchronous way. I don't want the browser stuck waiting until the final request has been completed. So, if you have any other idea/implementation, I can be a very open minded person ;)
p.s. I'm using TomCat 7
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
接下来的事情:
Something like next:
如果您愿意使用异步处理,我强烈建议使用事件侦听器。
请注意,Gecko 30.0(Firefox 30.0 等)由于对用户体验的负面影响而弃用了同步请求。
这(理解事件监听器)当然是异步的,并在响应到达后立即对其进行处理。
到目前为止,onreadystate 的改变可能会带来很多并发症和头痛。当您处理多个响应并且响应处理的顺序很重要时,尤其如此。
当您想要在响应到达时对其进行处理时,有一种简单的方法可以将 EventListener 添加到每个请求。
...
...您甚至可以自定义您要处理的状态。这些是当前允许的响应状态:
I'd strongly suggest using the Event Listeners in case You're willing to use asynchronous processing.
Note that Gecko 30.0 (Firefox 30.0 etc.) deprecated the synchronous requests due to negative impact on user's experience.
This (understand Event Listener) is of course asynchronous and processes the responses as soon as it arrives.
So far the onreadystatechange could bring a lot of complications and headaches. This is especially true when You're handling more than one responses and the order of the response processing matters.
When You want to process the responses as it arrives there is a simple way to add EventListener to each of the requests.
...
... You can even customize the state You're going to process. These are the currently allowed states of response:
您必须使用“this”而不是 arrXhr[intIcint]
You have to use "this" instead arrXhr[intIcint]
不要为每个产品 ID 同时发送多个请求,而是将所有 ID 包装到一个数组中,将其序列化并仅使用一个请求。
通过请求仅发送serializedIds变量
instead of sending multiple simultanous requests for each product id, wrap all the ids into an array, serialize it and use only one request.
send only the serializedIds variable through the request