使用 Dojo 进行批量 Ajax 请求的多种处理方式.docx
- 文档编号:26282589
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:11
- 大小:19.09KB
使用 Dojo 进行批量 Ajax 请求的多种处理方式.docx
《使用 Dojo 进行批量 Ajax 请求的多种处理方式.docx》由会员分享,可在线阅读,更多相关《使用 Dojo 进行批量 Ajax 请求的多种处理方式.docx(11页珍藏版)》请在冰豆网上搜索。
使用Dojo进行批量Ajax请求的多种处理方式
使用Dojo进行批量Ajax请求的多种处理方式
引言
在阅读本文之前,您需要具备以下知识:
Ajax技术:
Ajax的英文全名是:
AsynchronousJavaScriptandXML,从名字可以看出Ajax是一种异步的与服务器业务交互的方式。
通常,在浏览器内运行的JavaScript代码都是单线程的。
Ajax的异步交互方式使得前台的JavaScript程序不会阻塞在等待服务器响应的过程中。
从而使前台程序能够一直保持激活和响应性。
有关Ajax的内容请参考Ajax技术资源中心。
Dojo框架:
Dojo是一个强大的前端框架,它提供了方便的Ajax方法、丰富的小部件、数据结构、辅助函数、效果和布局帮助。
有关Dojo的详细介绍请参考Dojo技术专题。
XMLHttpRequest对象:
这是一个JavaScript对象,用于向服务器发送请求和接收服务器的响应。
详细介绍请参考相关资源。
异步编程模式:
这种模式在web编程中变得越来越重要,通常用于执行时间可能较长的操作。
异步编程模式不会等待长时间的操作完成或是造成阻塞,而是立即返回一个代表该操作的对象。
操作成功或者失败之后会调用事先对该对象注册的回调函数。
有关异步编程模式在web编程中的应用请参考相关资源。
并发和串行Ajax请求:
顾名思义,并发Ajax请求是指客户端同时发送多个Ajax请求至服务器端;串行Ajax请求是指客户端在一个Ajax请求返回之后再发送下一个Ajax请求。
Dojo的应用将贯穿本文,选择Dojo的主要原因有以下两点:
Dojo提供了专门用于异步编程模式的对象:
dojo.Deferred。
并且提供了很多进一步操作Deferred对象的机制和方法。
通过这些机制和方法能够方便的管理多个dojo.Deferred对象。
Dojo封装了一些静态函数(dojo.xhr函数)使得开发人员能够很简单的触发Ajax请求。
同时,dojo.xhr函数返回一个Deferred对象用于进行异步编程操作。
基于上述内容,本文的主要内容可以归纳如下:
描述dojo.xhr函数的使用、如何将其应用于异步编程模式和如何利用异步编程模式实现小规模的批量Ajax请求管理
详细介绍用dojo.DeferredList和dojox.lang.async.par实现任意规模的并发Ajax请求
详细介绍用dojox.lang.async.seq实现任意规模的串行Ajax请求
回页首
准备工作
服务器端业务描述
由于本文主要讨论客户端实现Ajax请求。
在此不介绍服务器端的实现方式,并且认为服务器已经实现了所有我们需要的功能,仅以最简单的方式描述服务器端的业务。
让我们用一个示例来说明,图1展示了服务器与客户端的交互。
图1.客户端与服务器端数据交互示
现在在服务器端有一个音乐管理系统,里面的音乐按照风格进行分类。
服务器提供两类REST服务:
/music/{categoryOfMusic}返回某一个分类的所有歌曲的概要信息
/music/{nameOfSong}返回某一首歌曲的详细信息
客户端与服务器端的数据以JSON格式进行交互。
准备开发环境和调试工具
下载并安装Firefox浏览器,并安装Firebug插件。
回页首
使用Dojo进行基本的Ajax请求处理
dojo.xhr的使用方法
HTTP协议中的四种请求是分别是:
Get(读取),Post(更新),Put(创建),Delete(删除)。
Dojo以XmlHttpRequest对象为基础,提供了一组静态函数来支持这些HTTP请求。
这些方法定义在dojo/_base/xhr.js中,因此在使用的时候不需要显式的引用。
清单1显示了一个示例,这个示例获取所有轻音乐歌曲,并将获得的数据打印在Firebug的console面板上。
清单1.dojo.xhrGet的使用
dojo.xhrGet({
url:
"/music/softMusic",
sync:
false,
handleAs:
"json",
handle:
function(response,ioArgs){
console.log(response);
}
});
sync表示当前的xhr函数在数据返回前是否阻塞,这个值默认是false,即不阻塞。
有关Dojo中xhr函数的详细使用请参考掌握Dojo工具包,第2部分:
XHR框架与Dojo以获得更多的信息。
服务器以JSON格式返回歌曲信息如清单2所示:
清单2.服务器端返回/music/{categoryOfMusic}数据示例
{
"songs":
[
{
name:
"softMusic1",
singer:
"A",
category:
"soft"
},
{
name:
"softMusic2",
singer:
"B",
category:
"soft"
},
{
name:
"softMusic3",
singer:
"C",
category:
"soft"
}
]
}
dojo.Deferred对象和为dojo.xhr函数添加回调函数
Dojo提供的所有xhr函数都会返回一个"dojo.Deferred"对象。
更多有关"dojo.Deferred"的信息,请参考dojo.Deferred参考文档。
Deferred对象是Dojo提供的用于异步编程模式的强大工具。
"dojo.Deferred"有三个状态,初始化时是"unresolve"状态;当它所等待的事件发生时,进入"resolve"状态;当发生错误了,进入"reject"状态。
当Deferred对象由"unresolve"状态进入"resolve"状态或"reject"状态时,会调用事先注册的回调函数。
对于dojo.xhr返回的Deferred对象,所注册的回调函数会在Ajax请求返回时或者出错时调用。
通过注册回调函数,可以替代的dojo.xhr中的handle方法。
例如上面的一段代码可以写成如下所示:
清单3.为dojo.xhrGet添加回调函数
vardeferred=dojo.xhrGet({
url:
"/music/softMusic",
handleAs:
"json"
});
deferred.addBoth(function(response){
console.log(response);
});
addBoth是为正常返回和出错返回添加相同的回调函数。
与dojo.xhr函数的参数handle起相同作用。
基于回调函数的小规模批量Ajax请求处理
因为Ajax请求是一种异步操作,客户端不知道什么时候能获得返回的数据,所以进行批量Ajax请求时,客户端不能很好的同时管理多个Ajax请求返回的数据。
例如,当需要多个Ajax请求都返回之后将得到的数据一起输出,不论是分别监测这些Ajax请求还是延时一个足够长的时间以确保所有的Ajax请求都返回,都不是明智的方法。
dojo.xhr函数可以为Ajax请求添加任意的回调函数。
这样在前一次请求的回调函数中再发送Ajax请求。
当最后一个Ajax请求返回时,必然所有的Ajax请求都已经返回。
通过这种方法,可以实现小规模的批量Ajax请求管理。
例如,回到我们的音乐管理系统。
现在需要获取第3首轻音乐的详细信息,并输出在Firebug的console面板上。
由于我们事先不知道第3首轻音乐的名字,无法直接获取它的详细信息。
只能先获得所有的轻音乐,在返回的JSON格式数据中找到第三首音乐的概要信息,再发送一次Ajax请求获得该音乐的详细信息。
清单4展示了一种实现方式。
清单4.在回调函数中发送另一次Ajax请求
vardeferred=dojo.xhrGet({
url:
"/music/softMusic",
handleAs:
"json"
});
deferred.then(function(response){
varsongs=response.songs;
returndojo.xhrGet({
url:
"/music/"+songs[2].name,
handleAs:
"json"
});
},function(errResponse){
console.log(errResponse);
}).addBoth(function(response){
console.log(response);
});
Deferred对象的then方法接收两个参数,这两个参数都是函数,第一个函数在Deferred达到"resovled"时调用,第二个函数在Deferred达到"rejected"时调用。
服务器以JSON格式返回歌曲的详细信息如清单5所示:
清单5.服务器端返回/music/{nameOfSong}数据示例
{
name:
"softMusic3",
singer:
"C",
year:
"2012-03-21",
…
category:
"soft"
}
这种方法只能串行的处理多个Ajax请求,并且,随着Ajax请求数增多,所需要的代码也需要相应的增加,因此只适合进行小规模批量Ajax请求处理。
回页首
使用Dojo并发的处理多个Ajax请求
实现原理
由于HTTP协议是无状态的(Stateless),HTTP的无状态特性简化了服务器的设计,使服务器更容易支持大量并发的HTTP请求。
在客户端,采用Dojo作为开发工具,由于dojo.xhr函数返回的是一个"dojo.Deferred"对象。
因此,可以通过管理多个dojo.xhr函数返回的Deferred对象来管理多个并发的Ajax请求。
用dojo.DeferredList和dojox.lang.async.par实现比较
Dojo中有多种方法管理异步编程对象"dojo.Deferred"。
首先,可以用dojo.DeferredList管理多个Deferred对象。
dojo.DeferredList本身是一个dojo.Deferred的子类。
因此,它也有相应的三种状态,也有对应的回调函数。
DeferredList达到"resolved"的条件是所有它所管理的Deferred对象都达到"resolved"或"rejected"状态。
在下面的例子中,DeferredList达到"resolved"的条件是所有的Ajax请求都返回(不论是成功返回还是出错返回),而DeferredList的回调函数获得的参数是一个二元数值对的数组,二元数值对对应了各个Ajax请求的返回信息。
其中第一个数值是一个boolean值,表示Ajax请求是否成功返回;第二个数值是Ajax请求返回的信息。
不论各个Ajax请求的返回顺序如何,该数组的顺序对应于传入DeferredList的Deferred对象的顺序。
同时,我们也可以用dojox.lang.async模块中的一个静态函数dojox.lang.async.par管理并发的Ajax请求管理。
这个静态函数接受一个函数的数组作为参数,并返回一个"dojo.Deferred"对象。
在管理并发的Ajax请求时,可以使得传入的函数返回时调用dojo.xhr函数。
该函数返回的Deferred对象达到"resolved"状态的条件是上述函数数组中的函数成功返回或者函数返回的Deferred对象都达到"resolved"状态。
否则,该Deferred对象进入"rejected"状态。
该Deferred对象对应"resolved"状态的回调函数能够获得一个数组作为参数,这个数组包含了各个Ajax请求的成功返回信息。
不论各个Ajax请求的返回顺序如何,该数组的顺序对应于传入dojox.lang.async.par的函数的顺序。
并发处理多个Ajax请求的示例
现在,对于我们的音乐管理系统,我们要同时获得所有的轻音乐,民谣,乡村音乐,并在Firebug的console面板显示。
清单6展示了用上述的两种方法实现的示例。
清单6.并发处理Ajax请求示例
dojo.require("dojo.DeferredList");
dojo.require("dojox.lang.async");
functiongetSoftMusic(){
returndojo.xhrGet({
url:
"/music/softMusic",
handleAs:
"json"
});
}
functiongetFolkMusic(){
returndojo.xhrGet({
url:
"/music/folkMusic",
handleAs:
"json"
});
}
functiongetCountryMusic(){
returndojo.xhrGet({
url:
"/music/countryMusic",
handleAs:
"json"
});
}
//利用dojo.DeferredList处理并发的Ajax请求
vard1=getSoftMusic(),d2=getFolkMusic(),d3=getCountryMusic(),
defList=newdojo.DeferredList([d1,d2,d3]);
defList.then(function(results){
dojo.forEach(results,function(result){
console.log(result[1]);
});
});
//利用dojox.lang.async.par处理并发的Ajax请求
vararrayOfAjax=[getSoftMusic,getFolkMusic,getCountryMusic];
dojox.lang.async.par(arrayOfAjax)().then(function(results){
dojo.forEach(results,function(result){
console.log(result);
});
});
两种解决方案的对比
从上面的示例可以看出,上述的两种方法都是用一个Deferred对象管理多个Deferred对象(DeferredList是Deferred的子类,因此DeferredList的实例也可以认为是一个Deferred对象)。
通过为作为管理者的Deferred对象增加回调函数来通知客户端程序多个Ajax请求已经返回。
相比之下,用DeferredList更为灵活。
DeferredList在默认情况下,会完成所有的Ajax请求,即使某一个Ajax请求失败了,最后DeferredList仍能够触发"resolved"状态的回调函数,并将相应的信息置于回调函数的参数中。
而dojox.lang.async.par只会在所有的Ajax请求成功返回之后才会将各个Ajax请求的返回的信息传递给回调函数。
当某一个Ajax请求失败了,dojox.lang.async.par会将排在这个请求之后的所有Ajax请求取消。
并触发"rejected"状态的回调函数。
回页首
使用Dojo串行的处理多个Ajax请求
实现原理
利用前文中所述的方法可以串行的处理多个Ajax请求。
但是存在一个问题,当需要串行处理的Ajax请求较多时,代码将显得又乱又长。
并且,很多时候程序事先并不知道要串行处理多少个Ajax请求,因为这是由用户的操作决定的。
在dojox.lang.async模块中,有一个静态函数dojox.lang.async.seq能够很好的帮我们解决这些问题。
用dojox.lang.async.seq的实现和示例
dojox.lang.async.seq也是接受一个函数的数组作为参数,并返回一个"dojo.Deferred"对象。
在管理串行的Ajax请求时,可以使得传入的函数返回时调用dojo.xhr函数。
该函数返回的Deferred对象达到"resolved"状态的条件是上述函数数组中的函数成功返回或者函数返回的Deferred对象都达到"resolved"状态。
否则,该Deferred对象进入"rejected"状态。
回到之前的例子,现在我们需要删除轻音乐,民谣,乡村音乐。
但是很不幸,服务器规定删除操作不能并发进行,我们只能在删除一个分类之后再删除另一个分类。
清单7展示了实现的示例。
清单7.串行处理Ajax请求示例
dojo.require("dojox.lang.async");
functiondeleteSoftMusic(){
returndojo.xhrDelete({
url:
"/music/softMusic",
handle:
function(response){
console.log(response);
}
});
}
functiondeleteFolkMusic(){
returndojo.xhrDelete({
url:
"/music/folkMusic",
handle:
function(response){
console.log(response);
}
});
}
functiondeleteCountryMusic(){
returndojo.xhrDelete({
url:
"/music/countryMusic",
handle:
function(response){
console.log(response);
}
});
}
vararrayOfAjax=[deleteSoftMusic,deleteFolkMusic,getCountryMusic];
dojox.lang.async.seq(arrayOfAjax)().allBoth(function(result){
console.log(result);
});
当dojox.lang.async.seq管理的某一个Ajax请求失败了,排在其之后的Ajax请求将不再执行。
并且dojox.lang.async.seq返回的Deferred对象会进入"rejected"状态。
回页首
总结
通过以上的介绍和举例,我们了解了如何以Dojo作为工具,管理批量Ajax请求。
Ajax请求是一种异步操作,客户端无法知道这种异步操作什么时候返回,是否能成功返回。
因此,批量处理Ajax请求的难点在于同时管理。
本文讲述了一种结合dojo.xhr函数和dojo.Deferred对象的管理方式。
用这种方式能够以多种方式管理批量Ajax请求,希望能为您的实际应用带来一定的启发。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 使用 Dojo 进行批量 Ajax 请求的多种处理方式 进行 批量 请求 多种 处理 方式