最近在做公司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(2000); WriteSuccess(context, action, "2"); break; case "delay2Seconds": Thread.Sleep(1000); WriteSuccess(context, action, "1"); break; case "delay3Seconds": Thread.Sleep(3000); WriteSuccess(context, action, "3"); 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
相关推荐
本文实例讲述了javascript异步处理与Jquery deferred对象用法。分享给大家供大家参考,具体如下: 这是项目组老大整理的一些关于jquery 异步处理请求,以及使用 jquery deferred 对象的一些常见方法。虽然是项目上...
jquery Deferred 快速解决异步回调的问题 function ok(name){ var dfd = new $.Deferred(); callback:func(){ return dfd.resolve( response ); } return dfd.promise(); } $.when(ok(1),ok(2)).then(function...
对jQuery中的deferred的用法了一些了解,今天看到园子里的一篇文章:关于重构JS前端框架的失败经验(顺便怀念那些死去的代码),于是把我之前写的一个利用jQuery的deferred异步按顺序加载JS文件方案分享出来,欢迎...
主要介绍了jQuery通过deferred对象管理ajax异步的相关资料,需要的朋友可以参考下
Deferred.JS 可以轻松处理异步进程(如AJAX等)。 Deferred.JS 是JQuery Deferred objects的替代品。 (行为与 JQuery Deferred 相同)。 阅读以了解为什么您应该从 JQuery Deferred 迁移到 Deferred.JS。 要从 ...
HTML+CSS3+JS+JQuery实现七夕言情动画、面向对象程序设计、Deferred对象解决异步编程回调嵌套问题
Promises是一种令代码异步行为更加优雅的抽象,它很有可能是JavaScript的下一个编程范式,一个Promise即表示任务结果,无论该...本文以jQuery中$.Deferred对象为例讲解promise对象是如何处理异步问题,需要的朋友参考下
React式承诺使 jQuery.Deferred 承诺具有React性。关于Reactive-Promise 允许您使用承诺作为React数据源。 常见用例包括: 允许 Iron Router 路由等待一个或多个异步任务基于异步任务完成在模板中执行条件渲染使用...
介绍jquery中deferred来实现异步编程,以及它的使用
5. 异步队列 Deferred 5.1 概述 异步队列是一个链式对象,增强对回调函数的管理和调用,用于处理异步任务。 异步队列有三种状态:初始化(unresolved),成功(resolved),失败(rejected)。 执行哪些回调函数依赖...
jQuery.Deferred对象功能扩展。 新的jQuery.isNumeric()方法。 另外,在jQuery 1.7中移除了event.layerX和event.layerY这两个属性,以及jQuery.isNaN()和jQuery.event.proxy()方法,分别用event.originalEvent....
主要介绍了jQuery的promise与deferred对象在异步回调中的作用,需要的朋友可以参考下
android-deferred-object, 在 jQuery http上,Android实现延迟对象 Pattern的实现 Android延迟对象Android-Deferred-Object是一个of实用工具对象,可以以将多个回调 register 调回回调队列,调用回调队列和异步功能...
我们在开发程序的时候通常会碰到使用ajax加载数据显示到列表的情况。ajax默认使用异步加载(async:true)。为什么不使用同步呢,因为ajax同步加载会UI渲染线程阻塞的问题。通常表现为在加载大量数据时由于加载时间过...
接着详细分析了底层支持模块的源码实现,包括:选择器sizzle、异步队列deferred、数据缓存data、队列queue、浏览器功能测试support;最后详细分析了功能模块的源码实现,包括:属性操作attributes、事件系统events、...
资源名称:jQuery技术内幕:深入解析jQuery架构设计与...接着详细分析了底层支持模块的源码实现,包括:选择器 Sizzle、异步队列 Deferred、数据缓存 Data、资源太大,传百度网盘了,链接在附件中,有需要的同学自取。