最近在做公司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. [iOS]iPhone推送原理

    推送原理,先上图 说一下原理吧, 由App向iOS设备发送一个注册通知 iOS向APNs远程推送服务器发送App的Bundle Id和设备的UDID APNs根据设备的UDID和App的Bundle ...

  2. 使用StarUML画类图

    1.综述(What) StarUML是一种生成类图和其他类型的UML图表的工具. StarUML(简称SU),是一种创建UML类图,并能够自动生成Java的“stub code” 的工具.SU也可以做 ...

  3. 309. Best Time to Buy and Sell Stock with Cooldown

    题目: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...

  4. Docker基础技术:AUFS

    AUFS是一种Union File System,所谓UnionFS就是把不同物理位置的目录合并mount到同一个目录中.UnionFS的一个最主要的应用是,把一张CD/DVD和一个硬盘目录给联合 m ...

  5. 可视化MNIST之降维探索Visualizing MNIST: An Exploration of Dimensionality Reduction

    At some fundamental level, no one understands machine learning. It isn’t a matter of things being to ...

  6. storage size of ‘oldact’ isn’t known

    #include <signal.h> int main(){struct sigaction act, oldact;return 0;} dies with the message t ...

  7. marquee 笔记

    页面的自动滚动效果,可由javascript来实现, 但是有一个html标签 - <marquee></marquee>可以实现多种滚动效果,无需js控制. 使用marquee ...

  8. Weblogic控制器的部署

    WebLogic的安装 一 WebLogic安装 1.  打开WebLogic安装程序:oepe11_wls1031.exe(我们选用的是WebLogic 10.3g).如图1-1所示: 图1-1   ...

  9. 南阳理工ACM 括号匹配问题,并求出使得括号能够匹配需要新增的最小括号数(括号匹配(二))

    描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起 ...

  10. 每天一个小算法(Heapsort)

    #include "stdio.h" #include "stdlib.h" #define Num 10 Heap(int arr[],int i,int n ...