近日,内部推荐计划。当进入项目首页。。依照以往的习惯,应该将调用接口后运行的代码,放入ajax请求success内运行。这样当然能够,可是代码组织和可读性都没有那么高。
通过查看Jquery官网api发现了deferred
object(延迟对象)这个概念。
一、API文档的翻译:
延迟对象,在jquery1.5被引入。是调用jQuery.Deferred()方法生成的一个链式功用对象。
它能够注冊多个回调到回调队列,提取回调队列,传递不论什么异步或同步函数的成功或失败状态。
延迟对象是一个链式的,类似于jquery对象的链式,可是它有自己的方法。
在创建之后。你能够用不论什么以下涉及到的方法,不管是直接链式调用,还是保存这个对象到变量。并在这个变量上调用一个或多个方法。
- deferred.always()
加入操作方法。无论延迟对象是处于解决状态还是拒绝状态都被调用。
- deferred.done()
加入操作方法。仅仅有延迟对象处于已解决状态才被调用
- deferred.fail()
加入操作方法,仅仅有延迟对象处于被拒绝状态才会被调用
- deferred.isRejected()
推断一个延迟对象是否处于被拒绝状态
- deferred.isResolved()
推断一个延迟对象是否处于已解决状态。
- deferred.notify()
调用一个给定变量的延迟对象上的进行中的回调。
- deferred.notifyWith()
调用一个给定变量和上下文的延迟对象上的进行中的回调。
- deferred.pipe()
用来过滤and或or链式延迟的效用方法
- deferred.progress()
当延迟对象生成进行中通知时,加入操作被调用。
- deferred.promise()
返回延迟允诺对象。
- deferred.reject()
拒绝一个延迟对象而且调用不论什么给定參数的失败回调。
- deferred.rejectWith()
拒绝回调对象。调用不论什么给定上下文和參数的失败回调。
- deferred.resolve()
解决一个延迟对象。而且调用不论什么给定參数的完毕回调。
- deferred.resolveWith()
解决一个延迟对象。而且调用不论什么给定上下文和參数的完毕回调。
- deferred.state()
推断当前延迟对象状态。
- deferred.then()
当延迟对象被解决、拒绝或进行中加入方法被调用。
- jQuery.Deferred()
延迟对象的构造函数。
- jQuery.when()
提供一个方法运行基于一个或多个对象的回调函数,回调函数常常是代表异步事件的延迟对象
- .promise()
当全部的绑定到集合、队列或没有的动作被完毕返回一个promise对象。
二、延迟对象分析与使用:
不难得出结论,以上API包含了延迟对象的构建、延迟状态设定方法、延迟状态监听方法。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveWluZ3lpbGVkaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >
延迟对象的数据结构
延迟对象包含三种状态:resolved(已解决)、rejected(未解决)、progress(进行中)。
这三种状态能够用延迟对象state方法实时查看。
延迟对象状态查看
延迟对象是jquery的回调函数解决方式,延迟顾名思义就是延迟到未来某个点再运行,类似jquery 动画函数中delay方法,差别在于后者是延迟固定时间。延迟对象则是通过固定状态推断延迟运行的时机。
var dtd = $.Deferred(); // 新建一个deferred对象 var wait = function(dtd){ var tasks = function(){ alert("运行完成!"); dtd.resolve(); // 改变deferred对象的运行状态 }; setTimeout(tasks,5000); return dtd; }; $.when(wait(dtd)) .done(function(){ alert("哈哈,成功了! "); }) .fail(function(){ alert("出错啦! "); });
上述代码运行流程图:
上述代码样例,延迟对象定义为一个全局对象。这样就会造成延迟状态。能够在不论什么时间进行更改。
改进的方法一:
var dtd = $.Deferred(); // 新建一个Deferred对象 var wait = function(dtd){ var tasks = function(){ alert("运行完成!"); dtd.resolve(); // 改变Deferred对象的运行状态 }; setTimeout(tasks,5000); return dtd.promise(); // 返回promise对象,promise对象仅仅开放与状态无关的方法。即那三种状态方法不开放,无法设置 }; var d = wait(dtd); // 新建一个d对象。改为对这个对象进行操作 $.when(d) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦! "); }); d.resolve(); // 此时,这个语句是无效的
上述代码,在wait函数返回值是一个promise对象,由下图promise对象数据结构不难发现,promise对象拥有除了改动状态方法以外延迟对象的全部方法,也就是说。promise对象无法改变运行状态,这样就行防止外界对状态的更改。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveWluZ3lpbGVkaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >
promise对象的数据结构
改进方法二:
将延迟对象构建成函数内部的局部变量,这样更好的实现了封装,防止外部对状态进行改变。
var wait = function(dtd){ var dtd = $.Deferred(); //在函数内部,新建一个Deferred对象 var tasks = function(){ alert("运行完成!"); dtd.resolve(); // 改变Deferred对象的运行状态 }; setTimeout(tasks,5000); return dtd.promise(); // 返回promise对象 }; $.when(wait()) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
改进方法三:
直接将函数名作为$.Deferred()參数传入。$.Deferred()所生成的延迟对象会作为wait函数參数传入函数。
var wait = function(dtd){ var tasks = function(){ alert("运行完成。"); dtd.resolve(); // 改变Deferred对象的运行状态 }; setTimeout(tasks,5000); return dtd.promise(); // 返回promise对象 }; $.Deferred(wait) .done(function(){ alert("哈哈,成功了。"); }) .fail(function(){ alert("出错啦! "); });
$.Deferred()方式运行状态
三、项目使用情况:
乐帝在内推项目中使用的是另外一种方法,即将延迟对象作为局部变量定义,并返回promise对象。这里promise对象与延迟对象除了不能改变状态。对延迟状态的记录及监听方法都同样。
function loadInternalHost() { var dtd = $.Deferred(); dtd.resolve(); return dtd.promise();//在原defferred对象上返回还有一个deferred对象。两个对象都会记录最初deferred对象状态,但后者不能改变状态,其它方法一致 }
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveWluZ3lpbGVkaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >
promise对延迟状态的记录
当分别调用两个接口时。延迟监听函数同意为多个事件指定一个回调。
例如以下代码,分别取得内推城市及内推公告两部分数据后,运行兴许载入数据的动作。
$.when(getInternalRecommendCitys(), getComment()).done(function () { getInternalRecommendJobAdList(oldSearchData.keyWord, oldSearchData.locId); }); function getInternalRecommendCitys() { var dtd = $.Deferred(); $.ajax({ type: "get", data: { "openId": openId }, dataType: "json", url: "../api/InternalInfo/InternalRecommendCitys", success: function (data) { $city = $("#citySelect"); for (var i = 1; i < data.length; i++) { $str = $("<option></option>"); $str.text(data[i].name); $str.val(data[i].value); $city.append($str); dtd.resolve(); }//将可选城市导入到选择列表 }, error: function () { dtd.resolve(); } }); return dtd.promise(); } function getComment() { var dtd = $.Deferred(); $.ajax({ type: "get", data: { "openId": openId }, dataType: "json", url: "../api/InternalInfo/GetComment", success: function (data) { $(".notice-content pre").html(data.data); dtd.resolve(); }, error: function () { dtd.resolve(); } });//获取公告数据 return dtd.promise(); }
版权声明:本文博主原创文章。博客,未经同意不得转载。