Ajax Queue/Sync
在服务器中使用Ajax调用成为Web2.0公司度量自身的度量指标。我们已经多次讨论过,在jQuery中使用Ajax就像调用普通的方法一样简单。这意味着您可以轻松地调用任何服务器端Ajax函数,就像调用客户端的JavaScript函数一样。但是美中存在一些不足之处,当对服务器进行过多的Ajax调用时,就会出现一些负面效应。如果Web应用程序使用的Ajax调用过多,就会导致问题。
第一个问题是一些浏览器限制打开的服务器连接的数量。在Internet Explorer中,当前版本仅支持打开2个服务器连接。Firefox支持打开8个连接,但仍然是一个限制。如果Web应用程序不对Ajax调用进行控制,它就很可能打开2个以上的连接,尤其是服务器端调用属于时间密集型调用时。这个问题可能源于Web应用程序的不良设计,或用户不对请求加以限制。不管是那种情况都是不可取的,因为您不希望由浏览器决定使用哪些连接。
另外,因为调用是异步的,不能保证从服务器返回的响应的顺序与发送时一样。例如,如果您几乎同时发出2个Ajax调用,您就不能保证服务器的响应是以相同的顺序返回。因此,如果第二个调用依赖于第一个调用的结果,那么就会出现问题。想象这样一种场景,其中第一个调用获取数据,第二个调用在客户端操作该数据。如果第二个调用的响应返回得比第一个Ajax调用快,那么您的代码就会导致错误。您完全不能保证响应速度。当调用更多时,就更容易导致问题。
jQuery的创建者意识到这个潜在的问题,但同时也认识到它仅会给1%的Web应用程序带来问题。但1%开发Web应用程序的开发人员需要一个解决办法。因此创建了一个插件,通过创建一个Ajax Queue和一个Ajax Sync来筛查该问题。Queue和Sync的功能是很相似的:Queue一次发出一个Ajax调用,并且等待其响应返回之后才发出另一个调用。Sync几乎同时发出多个调用,但调用的响应是按先后顺序返回的。
通过在客户端控制Ajax调用解决了超载问题,同时也控制和规范了将响应发送回客户端的方式。现在,您可以确保知道响应返回到客户端的顺序,从而可以根据事件的顺序编写代码。我们看看这个插件是如何工作的,以及如何在您的代码中使用它(见清单7)。记住,这仅是为1%的Web应用程序设计的,它们拥有多个Ajax调用,并且后一个调用严重依赖于前一个调用的结果。这个示例不是调用相互依赖的例子,但它能够向您展示如何使用该插件(要为这个插件的应用创建一个完美的真实例子,并让其易于理解是很困难的)。
- varnewRow="<trid='?'>"+
- "<td><inputtypeinputtype=checkboxvalue='?'></td>"+
- "<td>?</td>"+
- "<td>?</td>"+
- "<td>?</td>"+
- "<td>?</td></tr>";
- $("#mailtable").everyTime(30000,"checkForMail",function(){
- //byusingtheAjaxQueuehere,wecanbesurethatwewillcheckformail
- //every30seconds,butONLYifthepreviousmailcheckhasalreadyreturned.
- //Thisactuallywouldbebeneficialinamailapplication,ifonecheckfor
- //newmailtakeslongerthan30secondstorespond,wewouldn'twantthe
- //nextAjaxcalltokickoff,becauseitmightduplicatemessages(depending
- //ontheserversidecode).
- //So,byusingtheAjaxQueueplug-in,wecanensurethatourWebclient
- //isonlycheckingfornewmailonce,andwillneveroverlapitself.
- $.ajaxQueue({
- url:"check_for_mail.jsp",
- success:function(data)
- {
- varmessage=eval('('+data+')');
- if(message.id!=0)
- {
- varrow=newRow.replace("?",message.id);
- rowrow=row.replace("?",message.id);
- rowrow=row.replace("?",message.to);
- rowrow=row.replace("?",message.from);
- rowrow=row.replace("?",message.subject);
- rowrow=row.replace("?",message.sentTime);
- $("#mailtabletbody").prepend(row);
- $("#mailtable#"+message.id).addClass("mail_unread").addClass("messageRow");
- $("#mailtable#"+message.id+"td").addClass("mail");
- $("#mailtable:checkbox").addClass("selectable");
- }
- }
- });
记住:如果您的应用程序有多个相互依赖的Ajax调用,那么要考虑使用Ajax Queue或Ajax Sync。