利用 Jquery Deferred 异步你的程序
最近在做公司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 异步你的程序的更多相关文章
- 利用jQuery.validate异步验证用户名是否存在
转:http://www.cnblogs.com/linzheng/archive/2010/10/14/1851781.html HTML头部引用: <script type="te ...
- 使用 jQuery Deferred 和 Promise 创建响应式应用程序
这篇文章,我们一起探索一下 JavaScript 中的 Deferred 和 Promise 的概念,它们是 JavaScript 工具包(如Dojo和MochiKit)中非常重要的一个功能,最近也首 ...
- jquery.Deferred promise解决异步回调
我们先来看一下编写AJAX编码经常遇到的几个问题: 1.由于AJAX是异步的,所有依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套,ajax等异步操作越多,嵌套层次就会越 ...
- 利用jquery.form实现异步上传文件
实现原理 目前需要在一个页面实现多个地方调用上传控件上传文件,并且必须是异步上传.思考半天,想到通过创建动态表单包裹上传文件域,利用jquery.form实现异步提交表单,从而达到异步上传的目的,在上 ...
- 异步提交form的时候利用jQuery validate实现表单验证
异步提交form的时候利用jQuery validate实现表单验证相信很多人都用过jquery validate插件,非常好用,并且可以通过下面的语句来自定义验证规则 // 电话号码验证 ...
- javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方式
我们先来看一下编写AJAX编码常常遇到的几个问题: 1.因为AJAX是异步的,全部依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套.ajax等异步操作越多,嵌套层次就会越 ...
- jQuery异步框架探究2:jQuery.Deferred方法
(本文针对jQuery1.6.1版本号)关于Deferred函数的描写叙述中有一个词是fledged,意为"羽翼丰满的",说明jQuery.Deferred函数应用应该更成熟. 这 ...
- jQuery Deferred和Promise的使用介绍:
deferred对象是从jquery1.5.0引入的一个新对象,ES6也引入了Promise的正式规范. 抽象来说,deferreds 可以理解为表示需要长时间才能完成的耗时操作的一种方式,相比于阻塞 ...
- 使用jQuery+PHP+Mysql实现抽奖程序
抽奖程序在实际生活中广泛运用,由于应用场景不同抽奖的方式也是多种多样的.本文将采用实例讲解如何利用jQuery+PHP+Mysql实现类似电视中常见的一个简单的抽奖程序. 查看演示 本例中的抽奖程序要 ...
随机推荐
- 预编译头文件 StdAfx.h
预编译头文件: 最常见的使用场景就是 StdAfx.h 文件,在这个文件中包含常用的头文件,比如windows.h,cstdio,string,别的 .cpp 文件去包含 StdAfx.h 头文件.编 ...
- Heap和Heapify
最近复习数据结构,又回去再看塞神的课件,看到PriorityQueue的实现.自己也根据塞神的代码写一写. 下面使用Binary Heap实现了一个简单的 Max-oriented PriorityQ ...
- C++:异常的处理
6.4 异常处理 程序中常见的错误分为两大类:编译时期的错误和运行时期的错误. 编译时期的错误比较简单容易发现:主要是语法错误,如关键字拼写错误.缺分号.括号不匹配等 运行时期的错误比较难发现,甚至是 ...
- Ubuntu 13.10 安装Qt5
Qt5在Ubuntu的软件中心是找不到的,只能从Qt的官网下载安装. http://qt-project.org/downloads,选择完整的Linux版本(qt-linux-opensource- ...
- js获取滚动条距离浏览器顶部,底部的高度,兼容ie和firefox
做web开发经常会碰到需要获取浏览器的滚动条与顶部和底部的距离,然后做相应的处理动作.下面作者就如何通过js来获取浏览器滚动条距离浏览器顶部和底部的高度做一下分享,这个是同时兼容ie和firefox的 ...
- dojo 十一 jsonp
官方教程:Getting Jiggy with JSONPDojo对Ajax实现的框架XHR的功能很强大,但 XHR 框架的函数有一问题就是不能跨域访问,浏览器不允许 XHR 对象访问其他域的站点.此 ...
- Oracle —— 表结构相关的SQL
1.表基本信息(Table) select * from user_tables t, user_tab_comments c where c.table_name = t.table_name an ...
- 第三方登录(1)OAuth(开放授权)简介及授权过程
3个角色:服务方,开发者,用户 a.用户在第在服务注册填写个人信息, b.服务方开放OAuth, c.开发者在服务方申请第3方登录,在程序中得到令牌后,经用户同意,可得到用户的个人信息. OAuth ...
- How to: Synchronize Files by Using Managed Code
The examples in this topic focus on the following Sync Framework types: FileSyncProvider FileSyncOpt ...
- Order to Cash Process
order to cash process steps can be listed as below · Enter the Sales Order · Book the Sales Order · ...