- 由DOM对象触发AJAX请求
- 生成AJAX对象,并检测当前并发请求数量是否大于最大请求上限。如果大于上限AJAX对象压入队列,否则直接发送请求,并且增加并发请求数目。
- 如果AJAX请求完成,进入完成后处理。结束后并发数目减一,之后检测队列是否有等待请求,如果有发送队首AJAX对象请求。
在分析上述AJAX应用的流程时我们发现,制约AJAX使用的两个地方。
- 如何将触发AJAX异步请求的DOM和相关参数传入onreadystatechange函数,从而更好的进行后续处理。
- 如何有效地控制并发请求的对服务器的负载问题,即控制批量触发的AJAX请求有序和可控的发送到远端服务器。
针对第一个问题,我这里采用的是引入嵌套匿名函数的方法达到各浏览器的兼容性。相应代码可参阅函数processRequest。在这个函数中,示例中指采用了两个参数,一是识别并发请求触发AJAX对象本身(这在并发多线程处理时是很重要的),另一个是触发AJAX请求的DOM对象本身的ID名称。当然还可以引入更多需要的参数用于AJAX请求完成后的处理,并在函数processEcho添加相应的代码。由于考虑到可能处理的AJAX请求回复的内容可能是针对requestXML,该函数传入参数是AJAX对象而不是requestText本身,当然可以跟据自己的需求修改这一点。
第二个问题的处理过程中采用了类似队列线形进出的方式,将超过最大并发请求的AJAX对象的请求暂缓发送,先将AJAX对象压入队列。等到先期发送对象完成自身请求后,再检测队列是否为空,如果不空再将队列首的AJAX的对象请求发送出去。这样既满足了服务器负载的考虑又照顾到AJAX请求发送的及时性。
JavaScript语言: Ajax并发与控制代码示例
01 var max_session=10;
02 var sessions=0;
03 var requestQue=new Array();
04 function createRequest(method, url, async, objID)
05 {
06 var request = new Object();
07 if (window.ActiveXObject) request.ajax = new ActiveXObject("Microsoft.XMLHTTP");
08 else if (window.XMLHttpRequest) request.ajax = new XMLHttpRequest();
09
10 if (request.ajax)
11 {
12 request.url=url;
13 request.method=method;
14 request.async=async;
15 request.objID=objID;
16 if(sessions<max_session)
17 {
18 sessions++;
19 sendRequest(request);
20 return;
21 }
22 else
23 {
24 requestQue.push(request);
25 }
26 }
27 }
28
29 function sendRequest(request)
30 {
31
32 request.ajax.open(request.method, request.url, request.async);
33 request.ajax.onreadystatechange = processRequest(request.ajax,request.objID);
34 request.ajax.send(null);
35 }
36
37 function checkQue()
38 {
39 if (sessions<max_session || requestQue.length>0)
40 {
41 sessions++;
42 var request = requestQue.shift();
43 if(request)
44 {
45 //Do something before sending request about object
46 preworkBeforeRequest(objID);
47 sendRequest(request);
48 }
49 }
50 }
51
52 function processRequest(request,objID)
53 {
54 return function()
55 {
56 if(request.readyState!=4||request.status!=200) return false;
57 //Handle the response text or XML
58 processEcho(request,objID);
59 sessions--;
60 checkQue();
61 };
62
63 }
64
65 function preworkBeforeRequest(objID)
66 {
67 //Do something before sending request about object
68
69 }
70
71 function processEcho(request,objID)
72 {
73 echoText=requst.responseText;
74 echoXML=request.responseXml;
75 //Do something related with echo Text
76
77 //Do something related with echo XML
78
79 //Do something related with ObjID
80
81 }