最近在做公司QA系统改造时,有这样的一个场景.

QA系统中有些数据项需要从JIRA平台(一个国外项目与事务跟踪工具)中获取,JIRA平台提供了很完善的Rest API.

现在的要求是,在QA系统中提交项目时,必须先从JIRA平台获取很多的数据项,每次请求的Rest API都不一样,

同时必须等所有请求都成功返回数据后才能提交项目.

因为之前对Jquery Deferred有过研究,发现这个场景用它来实现再合适不过了.

这里对Jquery Deferred不做过多讲解了,不了解的同学可以先看下面的文章.

http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html

http://www.cnblogs.com/justany/archive/2013/01/20/2867444.html

好了,现在让我们来模拟上面的场景.(文章最后有完整DEMO下载)

假设我们获取数据项的请求全都由JqueryHandler.ashx来处理,在handler里面用Thread.Sleep()来模拟请求Rest API时的网络延迟.

 public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json"; string action = context.Request.Form["Action"];
//用Thread.Sleep()模拟请求Rest API时的网络延迟
switch (action)
{
case "delay1Seconds":
Thread.Sleep();
WriteSuccess(context, action, "");
break;
case "delay2Seconds":
Thread.Sleep();
WriteSuccess(context, action, "");
break;
case "delay3Seconds":
Thread.Sleep();
WriteSuccess(context, action, "");
break;
default:
break;
}
} public void WriteSuccess(HttpContext context, string action, string seconds)
{
//输出JSON结果
string index = context.Request.Form["Index"];
string json = "{\"flag\":0,\"msg\":" + seconds + ",\"Index\":" + index + "}";
context.Response.Write(json);
}

数据服务端模拟好了之后,接下来让我们来发出获取数据项的请求.

    <script src="Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () { $("#btn_Request").click(
function () {
$("#div_Content").html(""); //模拟请求Handler地址
var requestUrl = "JqueryHandler.ashx"; //ajax请求 action名称数组
var requestInfoArr =
[
{ Action: "delay1Seconds" },
{ Action: "delay2Seconds" },
{ Action: "delay3Seconds" }
]; //用于保存Jquery Defered对象
var deferredOBJ = []; //创建3个 Jquery Deferred 对象
//与3个对 JqueryHandler.ashx 的异步请求一 一对应
for (var i = 0; i < requestInfoArr.length; i++) {
deferredOBJ[i] = $.Deferred(); var jsonData = requestInfoArr[i]; //记录当前ajax请求的索引,方便后面找到对应的Jquery Deferred对象
jsonData.Index = i; //发出ajax请求
$.ajax({
type: "POST",
dataType: "json",
url: requestUrl,
data: jsonData,
success: function (data, statu) {
//flag为0时表示请求成功
if (data.flag == 0) {
var result = requestInfoArr[data.Index].Action + " 请求成功,耗时:" + data.msg + "秒";
$("#div_Content").append($("<p/>").text(result)); //根据前面传过去的索引找到对应Deferred对象,将状态改成resolve(表示成功)
deferredOBJ[data.Index].resolve();
} else {
// 如果请求出错,将状态改成reject (表示失败)
//这里调用reject()后,会立即执行下面的fail()函数
deferredOBJ[data.Index].reject(data.msg);
}
},
error: function (data, statu) {
alert("ajax请求获取数据失败!");
}
});
} //使用$.when() 来控制3个异步请求的流程,保证所有异步请求都完成后再执行done函数
$.when(deferredOBJ[0], deferredOBJ[1], deferredOBJ[2])
.done(function () {
var result = "所有请求完成...";
$("#div_Content").append($("<p/>").text(result));
})
.fail(function (error) {
alert("从JIRA获取度量项数据失败, 请重试");
}); }); });
</script>

这里的巧妙之处在于 jsonData.Index = i;  这句代码,不然要就要写3个ajax请求,代码会显得臃肿.

如果不记录当前请求索引的话,后面的success,error函数就无法找到对应的Deferred对象来改变状态.

可能大家会问,为什么不用deferredOBJ[i]来获取,这是因为请求都是异步的,在success,error函数里来获取 i 永远都是2(因为requestInfoArr.length是2).

让我们来验证一下这3个ajax请求是不是都是异步执行的.

用firebug可以看到3个ajax请求是同时发出的,这样3个请求只花了3.09s.

如果3个ajax请求是顺序执行的话就需要花费 2.03s+1.06s+3.09s=6.18s, 使用jquery deferred节约了一倍的时间.

最后附上程序运行截图和DEMO程序:

完整DEMO下载:Jquery Deferred

 

利用 Jquery Deferred 异步你的程序的更多相关文章

  1. 利用jQuery.validate异步验证用户名是否存在

    转:http://www.cnblogs.com/linzheng/archive/2010/10/14/1851781.html HTML头部引用: <script type="te ...

  2. 使用 jQuery Deferred 和 Promise 创建响应式应用程序

    这篇文章,我们一起探索一下 JavaScript 中的 Deferred 和 Promise 的概念,它们是 JavaScript 工具包(如Dojo和MochiKit)中非常重要的一个功能,最近也首 ...

  3. jquery.Deferred promise解决异步回调

    我们先来看一下编写AJAX编码经常遇到的几个问题: 1.由于AJAX是异步的,所有依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套,ajax等异步操作越多,嵌套层次就会越 ...

  4. 利用jquery.form实现异步上传文件

    实现原理 目前需要在一个页面实现多个地方调用上传控件上传文件,并且必须是异步上传.思考半天,想到通过创建动态表单包裹上传文件域,利用jquery.form实现异步提交表单,从而达到异步上传的目的,在上 ...

  5. 异步提交form的时候利用jQuery validate实现表单验证

    异步提交form的时候利用jQuery validate实现表单验证相信很多人都用过jquery validate插件,非常好用,并且可以通过下面的语句来自定义验证规则    // 电话号码验证    ...

  6. javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方式

    我们先来看一下编写AJAX编码常常遇到的几个问题: 1.因为AJAX是异步的,全部依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套.ajax等异步操作越多,嵌套层次就会越 ...

  7. jQuery异步框架探究2:jQuery.Deferred方法

    (本文针对jQuery1.6.1版本号)关于Deferred函数的描写叙述中有一个词是fledged,意为"羽翼丰满的",说明jQuery.Deferred函数应用应该更成熟. 这 ...

  8. jQuery Deferred和Promise的使用介绍:

    deferred对象是从jquery1.5.0引入的一个新对象,ES6也引入了Promise的正式规范. 抽象来说,deferreds 可以理解为表示需要长时间才能完成的耗时操作的一种方式,相比于阻塞 ...

  9. 使用jQuery+PHP+Mysql实现抽奖程序

    抽奖程序在实际生活中广泛运用,由于应用场景不同抽奖的方式也是多种多样的.本文将采用实例讲解如何利用jQuery+PHP+Mysql实现类似电视中常见的一个简单的抽奖程序. 查看演示 本例中的抽奖程序要 ...

随机推荐

  1. C#之你懂得的序列化/反序列化

    前言:写此文章一方面是为了巩固对序列化的认识,另一方面是因为本人最近在面试,面试中被问到“为什么要序列化”.虽然一直在使用,自己也反复的提到序列化,可至于说为什么要序列化,还真的没想过,所以本文就这样 ...

  2. ES6入门之Symbol

    ES5对象属性名都是字符串容易造成属性名的冲突. eg:var a = { name: 'lucy'}; a.name = 'lili';这样就会重写属性 ES6引入了一种新的原始数据类型Symbol ...

  3. android AsyncTask异步下载并更新进度条

    AsyncTask异步下载并更新进度条    //如果不是很明白请看上篇文章的异步下载 AsyncTask<String, Integer, String> 第一个参数:String 传入 ...

  4. linux内核编程笔记【原创】

    以下为本人学习笔记,如有转载请注明出处,谢谢 DEFINE_MUTEX(buzzer_mutex); mutex_lock(&buzzer_mutex); mutex_unlock(& ...

  5. MYSQL语句中SELECT语句及其子句的执行顺序

    SELECT语句的执行的逻辑查询处理步骤:(8)SELECT (9)DISTINCT(11)<TOP_specification> <select_list>(1)FROM & ...

  6. linux系统更改目录和文件的权限总结

    对于属于你的文件,可以按照自己的需要改变其权限位的设置.在改变文件权限位设置之前,要仔细地想一想有哪些用户需要访问你的文件(包括你的目录).可以使用c h m o d命令来改变文件权限位的设置.这一命 ...

  7. Getting Error "Invalid Argument to LOCATOR.CONTROL: ORG_LOCATOR_CONTROL='' in Material Requirements Form (文档 ID 1072379.1)

    APPLIES TO: Oracle Work in Process - Version 11.5.10.2 and later Information in this document applie ...

  8. Android 第三方应用接入微信平台(2)

    微信平台开放后倒是挺火的,许多第三方应用都想试下,毕竟可以利用微信 建立起来的关系链来拓展自己的应用还是挺不错的,可以节约很多在社交方 面的开销,我最近由于实习需要也在研究这个东西,不过发现网上的相关 ...

  9. HTML中多媒体的应用_Flash/MP3/设置可以活动的文字

    一.HTML中多媒体的应用_falsh动画(往网页中插入Flash动画) 1. Flash动画插入第一种方法:使用<embed>...</embed>标记动画会自动缩小 属性: ...

  10. IOS中(类似于进度条哪种效果)MBProgressHUD的使用

    1.显示HUD MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; hud.labelText = ...