关于JQ的$.deferred函数。参考网络文档

由于jQuery版本问题对Deferred对象的实现有所不同,具体请参照jQuery api

jQuery.Deferred()基于Promises/A规范实现,因为jQuery本身的设计风格,jQuery.Deferred()并没有完全遵循Promises/A规范。

jQuery在1.5版本中首次引入了Deferred。你可以通过jQuery.Deferred() 在未来某个时候 得到 ‘延时’返回值。 在此之前是无法单独使用的,Deferred作为对ajax模块较大重写的一部分添加进来。1.5和1.6版本包含deferred功能,可以使$.ajax() 接收调用完成及请求出错的回调,但却存在严重的耦合。新版本的jQuery提供了一些增强的方式来管理回调,提供更加灵活的方式建立回调,而不用关心原始的回调是否已经触发。 jQuery的Deferred对象支持多个回调绑定多个任务,任务本身既可以是同步也可以是异步的。

举个简单地例子,原来我们写异步的ajax请求是这么写:

$.ajax({
    url : ‘/echo/json/‘,
    dataType:"json",
    type:"POST",
    data : {json:JSON.stringify({‘name‘:"愚人码头"})},
    success : function (data) {
        $("#render-me").html(data.name);
    },
    error : function () { alert(‘gulp!‘); }
});
 

从 jQuery 1.5 开始,$.ajax()返回的jqXHR对象 实现了 Promise 接口, 使它拥有了 Promise 的所有属性,方法和行为。(见Deferred object获取更多信息)。为了让回调函数的名字统一,便于在$.ajax()中使用。jqXHR也提供.error() .success()和.complete()方法。所以我们可以这样写:

$.ajax({
    url : ‘/echo/json/‘,
    dataType:"json",
    type:"POST",
    data : {json:JSON.stringify({‘name‘:"愚人码头"})}
}).success (function (data) {
    $("#render-me").html(data.name);
}).error(function () { alert(‘gulp!‘); });

或者这样写:

$.ajax({
    url : ‘/echo/json/‘,
    dataType:"json",
    type:"POST",
    data : {json:JSON.stringify({‘name‘:"愚人码头"})}
}).done (function (data) {
    $("#render-me").html(data.name);
}).fail(function () { alert(‘gulp!‘); });

jQuery.Deferred对象:

了解jQuery.Deferred对象可以看下面这个表格。

jQuery.Deferred()
创建一个新的Deferred对象的构造函数,可以带一个可选的函数参数,它会在构造完成后被调用。

jQuery.when()
通过该方式来执行基于一个或多个表示异步任务的对象上的回调函数

jQuery.ajax() 执行异步Ajax请求,返回实现了promise接口的jqXHR对象
deferred.then( doneFilter [, failFilter ] [, progressFilter ] ) 当Deferred(延迟)对象解决,拒绝或仍在进行中时,调用添加处理程序。
deferred.done() 当延迟成功时调用一个函数或者数组函数.
deferred.fail() 当延迟失败时调用一个函数或者数组函数.。
deferred.always() 当Deferred(延迟)对象解决或拒绝时,调用添加处理程序。
deferred.resolve(ARG1,ARG2,…) 调用Deferred对象注册的‘done’回调函数并传递参数
deferred.resolveWith(context,args) 调用Deferred对象注册的‘done’回调函数并传递参数和设置回调上下文
deferred.isResolved 确定一个Deferred对象是否已经解决。
deferred.reject(arg1,arg2,…) 调用Deferred对象注册的‘fail’回调函数并传递参数
deferred.rejectWith(context,args) 调用Deferred对象注册的‘fail’回调函数并传递参数和设置回调上下文
deferred.promise() 返回promise对象,这是一个伪造的deferred对象:它基于deferred并且不能改变状态所以可以被安全的传递

具体查看API http://www.css88.com/jqapi-1.9/category/deferred-object/

jQuery延时实现的核心是jQuery.Deferred:一个可以链式调用的构造函数。…… 需要注意的是任何deferred对象的默认状态是unresolved, 回调会通过 .then() 、 .fail()等方法添加到队列,并在稍后的过程中被执行。

下面这张表格列举了,哪些事件会触发哪些回调:

Callbacks\ Events→
deferred.always() deferred.done() deferred.fail() deferred.progress()
deferred.notify()       触发
deferred.notifyWith()       触发
deferred.reject() 触发   触发  
deferred.rejectWith() 触发   触发  
deferred.resolve() 触发 触发    
deferred.resolveWith() 触发 触发    

灵活的 jQuery.Deferred对象

$.deferred()方法

作用是生成一个deferred对象。

  1. var deferred = $.deferred();

done() 和 fail()

这两个方法都用来绑定回调函数。done()指定非同步操作成功后的回调函数,fail()指定失败后的回调函数。

  1. var deferred = $.Deferred();
  2. deferred.done(function(value) {
  3. alert(value);
  4. });

它们返回的是原有的deferred对象,因此可以采用链式写法,在后面再链接别的方法(包括done和fail在内)。

resolve() 和 reject()

这两个方法用来改变deferred对象的状态。resolve()将状态改为非同步操作成功,reject()改为操作失败。

  1. var deferred = $.Deferred();
  2. deferred.done(function(value) {
  3. alert(value);
  4. });
  5. deferred.resolve("hello world");

一旦调用resolve(),就会依次执行done()和then()方法指定的回调函数;一旦调用reject(),就会依次执行fail()和then()方法指定的回调函数。

state方法

该方法用来返回deferred对象目前的状态。

  1. var deferred = new $.Deferred();
  2. deferred.state(); // "pending"
  3. deferred.resolve();
  4. deferred.state(); // "resolved"

该方法的返回值有三个:

  • pending:表示操作还没有完成。
  • resolved:表示操作成功。
  • rejected:表示操作失败。

notify() 和 progress()

progress()用来指定一个回调函数,当调用notify()方法时,该回调函数将执行。它的用意是提供一个接口,使得在非同步操作执行过程中,可以执行某些操作,比如定期返回进度条的进度。

  1. var userProgress = $.Deferred();
  2. var $profileFields = $("input");
  3. var totalFields = $profileFields.length
  4. userProgress.progress(function (filledFields) {
  5. var pctComplete = (filledFields/totalFields)*100;
  6. $("#progress").html(pctComplete.toFixed(0));
  7. });
  8. userProgress.done(function () {
  9. $("#thanks").html("Thanks for completing your profile!").show();
  10. });
  11. $("input").on("change", function () {
  12. var filledFields = $profileFields.filter("[value!=‘‘]").length;
  13. userProgress.notify(filledFields);
  14. if (filledFields == totalFields) {
  15. userProgress.resolve();
  16. }
  17. });

then()

then()的作用也是指定回调函数,它可以接受三个参数,也就是三个回调函数。第一个参数是resolve时调用的回调函数,第二个参数是reject时调用的回调函数,第三个参数是progress()方法调用的回调函数。

deferred.then( doneFilter [, failFilter ] [, progressFilter ] )
在jQuery 1.8之前,then()只是.done().fail()写法的语法糖,两种写法是等价的。在jQuery 1.8之后,then()返回一个新的deferred对象,而done()返回的是原有的deferred对象。如果then()指定的回调函数有返回值,该返回值会作为参数,传入后面的回调函数。

  1. var defer = jQuery.Deferred();
  2. defer.done(function(a,b){
  3. return a * b;
  4. }).done(function( result ) {
  5. console.log("result = " + result);
  6. }).then(function( a, b ) {
  7. return a * b;
  8. }).done(function( result ) {
  9. console.log("result = " + result);
  10. }).then(function( a, b ) {
  11. return a * b;
  12. }).done(function( result ) {
  13. console.log("result = " + result);
  14. });
  15. defer.resolve( 2, 3 );

在jQuery 1.8版本之前,上面代码的结果是:

  1. result = 2
  2. result = 2
  3. result = 2

在jQuery 1.8版本之后,返回结果是

  1. result = 2
  2. result = 6
  3. result = NaN

这一点需要特别引起注意。

  1. $.ajax( url1, { dataType: "json" } )
  2. .then(function( data ) {
  3. return $.ajax( url2, { data: { user: data.userId } } );
  4. }).done(function( data ) {
  5. // 从url2获取的数据
  6. });

上面代码最后那个done方法,处理的是从url2获取的数据,而不是从url1获取的数据。

利用then()会修改返回值这个特性,我们可以在调用其他回调函数之前,对前一步操作返回的值进行处理。

  1. var post = $.post("/echo/json/")
  2. .then(function(p){
  3. return p.firstName;
  4. });
  5. post.done(function(r){ console.log(r); });

上面代码先使用then()方法,从返回的数据中取出所需要的字段(firstName),所以后面的操作就可以只处理这个字段了。

有时,Ajax操作返回json字符串里面有一个error属性,表示发生错误。这个时候,传统的方法只能是通过done()来判断是否发生错误。通过then()方法,可以让deferred对象调用fail()方法。

  1. var myDeferred = $.post(‘/echo/json/‘, {json:JSON.stringify({‘error‘:true})})
  2. .then(function (response) {
  3. if (response.error) {
  4. return $.Deferred().reject(response);
  5. }
  6. return response;
  7. },function () {
  8. return $.Deferred().reject({error:true});
  9. }
  10. );
  11. myDeferred.done(function (response) {
  12. $("#status").html("Success!");
  13. }).fail(function (response) {
  14. $("#status").html("An error occurred");
  15. });

always()

always()也是指定回调函数,不管是resolve或reject都要调用。

pipe方法

pipe方法接受一个函数作为参数,表示在调用then方法、done方法、fail方法、always方法指定的回调函数之前,先运行pipe方法指定的回调函数。它通常用来对服务器返回的数据做初步处理。

promise对象

大多数情况下,我们不想让用户从外部更改deferred对象的状态。这时,你可以在deferred对象的基础上,返回一个针对它的promise对象。我们可以把后者理解成,promise是deferred的只读版,或者更通俗地理解成promise是一个对将要完成的任务的承诺。

你可以通过promise对象,为原始的deferred对象添加回调函数,查询它的状态,但是无法改变它的状态,也就是说promise对象不允许你调用resolve和reject方法。

  1. function getPromise(){
  2. return $.Deferred().promise();
  3. }
  4. try{
  5. getPromise().resolve("a");
  6. } catch(err) {
  7. console.log(err);
  8. }

上面的代码会出错,显示TypeError {} 。

jQuery的ajax() 方法返回的就是一个promise对象。此外,Animation类操作也可以使用promise对象。

  1. var promise = $(‘div.alert‘).fadeIn().promise();

$.when()方法

$.when()接受多个deferred对象作为参数,当它们全部运行成功后,才调用resolved状态的回调函数,但只要其中有一个失败,就调用rejected状态的回调函数。它相当于将多个非同步操作,合并成一个。

  1. $.when(
  2. $.ajax( "/main.php" ),
  3. $.ajax( "/modules.php" ),
  4. $.ajax( "/lists.php" )
  5. ).then(successFunc, failureFunc);

上面代码表示,要等到三个ajax操作都结束以后,才执行then方法指定的回调函数。

when方法里面要执行多少个操作,回调函数就有多少个参数,对应前面每一个操作的返回结果。

  1. $.when(
  2. $.ajax( "/main.php" ),
  3. $.ajax( "/modules.php" ),
  4. $.ajax( "/lists.php" )
  5. ).then(function (resp1, resp2, resp3){
  6. console.log(resp1);
  7. console.log(resp2);
  8. console.log(resp3);
  9. });

上面代码的回调函数有三个参数,resp1、resp2和resp3,依次对应前面三个ajax操作的返回结果。

when方法的另一个作用是,如果它的参数返回的不是一个Deferred或Promise对象,那么when方法的回调函数将 立即运行。

  1. $.when({testing: 123}).done(function (x){
  2. console.log(x.testing); // "123"
  3. });

上面代码中指定的回调函数,将在when方法后面立即运行。

利用这个特点,我们可以写一个具有缓存效果的异步操作函数。也就是说,第一次调用这个函数的时候,将执行异步操作,后面再调用这个函数,将会返回缓存的结果。

  1. function maybeAsync( num ) {
  2. var dfd = $.Deferred();
  3. if ( num === 1 ) {
  4. setTimeout(function() {
  5. dfd.resolve( num );
  6. }, 100);
  7. return dfd.promise();
  8. }
  9. return num;
  10. }
  11. $.when(maybeAsync(1)).then(function (resp){
  12. $(‘#target‘).append(‘<p>‘ + resp + ‘</p>‘);
  13. });
  14. $.when(maybeAsync(0)).then(function (resp){
  15. $(‘#target‘).append( ‘<p>‘ + resp + ‘</p>‘);
  16. });

上面代码表示,如果maybeAsync函数的参数为1,则执行异步操作,否则立即返回缓存的结果。

实例

wait方法

我们可以用deferred对象写一个wait方法,表示等待多少毫秒后再执行。

  1. $.wait = function(time) {
  2. return $.Deferred(function(dfd) {
  3. setTimeout(dfd.resolve, time);
  4. });
  5. }

使用方法如下:

  1. $.wait(5000).then(function() {
  2. alert("Hello from the future!");
  3. });

改写setTimeout方法

在上面的wait方法的基础上,还可以改写setTimeout方法,让其返回一个deferred对象。

  1. function doSomethingLater(fn, time) {
  2. var dfd = $.Deferred();
  3. setTimeout(function() {
  4. dfd.resolve(fn());
  5. }, time || 0);
  6. return dfd.promise();
  7. }
  8. var promise = doSomethingLater(function (){
  9. console.log( ‘已经延迟执行‘ );
  10. }, 100);

自定义操作使用deferred接口

我们可以利用deferred接口,使得任意操作都可以用done()和fail()指定回调函数。

  1. Twitter = {
  2. search:function(query) {
  3. var dfr = $.Deferred();
  4. $.ajax({
  5. url:"http://search.twitter.com/search.json",
  6. data:{q:query},
  7. dataType:‘jsonp‘,
  8. success:dfr.resolve
  9. });
  10. return dfr.promise();
  11. }
  12. }

使用方法如下:

  1. Twitter.search(‘intridea‘).then(function(data) {
  2. alert(data.results[0].text);
  3. });

deferred对象的另一个优势是可以附加多个回调函数。

    1. function doSomething(arg) {
    2. var dfr = $.Deferred();
    3. setTimeout(function() {
    4. dfr.reject("Sorry, something went wrong.");
    5. });
    6. return dfr;
    7. }
    8. doSomething("uh oh").done(function() {
    9. alert("Won‘t happen, we‘re erroring here!");
    10. }).fail(function(message) {
    11. alert(message)
    12. });
时间: 2024-11-07 16:38:44

关于JQ的$.deferred函数。参考网络文档的相关文章

JQuery之JQuery的版本 JQuery入门 属性获取 JQuery就绪函数 JS文档就绪函数和JQuery文档就绪函数的区别 JS对象和JQuery对象的区别 关于$的使用 多个JS库的冲突解决方案

JQuery的版本 JQuery入门 属性获取 JQuery就绪函数 JS文档就绪函数和JQuery文档就绪函数的区别 JS对象和JQuery对象的区别 关于$的使用 多个JS库的冲突解决方案 JQuery的版本 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>jQuery的版本</title> <

第2章 网络文档

第2章 网络文档 一.网络基线 解决网络问题的最简单途径是把当前配置和以前的配置相比较. 基线文档由不同的网络和系统文档组成,它包括: ? 网络配置表 ? 网络拓扑图 ? ES网络配置表 ? ES网络拓扑图 创建网络的注意事项: 1) 确定文档覆盖的范围: 2) 保持一致:收集网络中所有设备的相同信息: 3) 明确目标:了解文档的用途: 4) 文档易于使用和访问: 5) 及时维护更新文档. 二.网络配置表 网络配置表的通常目标是提供网络中使用的硬件和软件组成的列表,其组成有: 分级 项目 杂项信

连接SQLServer2005失败--[Microsoft][ODBC SQL Server Driver][DBNETLIB]一般性网络错误。请检查网络文档

连接SQLServer2005失败,错误信息: 错误类型:Microsoft OLE DB Provider for ODBC Drivers (0x80004005)[Microsoft][ODBC SQL Server Driver][DBNETLIB]一般性网络错误.请检查网络文档. 我的连接字符串是:driver={SQL Server};Server=192.168.10.139;database=TestFax;Uid=sa;pwd=xxxx; 奇怪的是,我将Server处写(loc

Oracle官方文档(11G r 2)【安装需要参考的文档】

Oracle的官方文档相关的笔记:仅供大家参考,欢迎大家前来指正.提出建议哦 步骤: 点击左上角的Master Book List 然后进入一个书本目录 然后找到如下图所示: 然后根据自己的系统的版本去找相应的文档就OK了 比如我的是RedHat的,那么我就选择 第三项 Database Installation Guide for Linux 这本书了 进入之后如下图 所示 此时直接选择 2.3 点击进入,即可以按照文档去安装Oracle了,但是英语不要太烂哦,嘿嘿,实在不行的话 先去补充一下

2.7全部内置函数(来自文档)

    Built-in Functions     abs() divmod() input() open() staticmethod() all() enumerate() int() ord() str() any() eval() isinstance() pow() sum() basestring() execfile() issubclass() print() super() bin() file() iter() property() tuple() bool() filte

cmd命令查看Python模块函数等帮助文档和介绍

dir函数式可以查看对象的属性 使用方法很简单,举os类型为例,在Python命令窗口输入 dir(‘os’) 即可查看os模块的属性 打开cmd命令窗口 ? 输入python(注意:计算机需要有Python环境,配置好Python环境变量) ? 输入dir('os')命令 ? 如何查看对象某个属性的帮助文档 ? 如要查看’os’的split属性,可以用__doc__, 使用方法为print(’os’.split.__doc__) print(’os’.split.__doc__) ? 查看对象

ubuntukylin基础 man 查看一些终端函数的帮助文档

镇场文:       学儒家经世致用,行佛家普度众生,修道家全生保真,悟易理象数通变.以科技光耀善法,成就一良心博客.______________________________________________________________________________________________________ 我的系统:UbuntuKylin 16.04 LTS 64bit code: result show: 学习英语很重要呀. 今天你man了吗? 是时候表演真正的man了! __

Python学习笔记#函数中使用文档,让你的函数更容易理解

>>> def intadd(a,b): 'this is a test of the doc of function' return a+b >>> intadd(2,3) 5 >>> intadd.__doc__ 'this is a test of the doc of function' >>>

EDID真实数据块,请参考标准文档仔细核对

数据格式的详细说明:http://en.wikipedia.org/wiki/Extended_display_identification_data 下面是一个例子: 解释如下: [ 28.637887] ******** Show Sink Info ******** [ 28.637895] Max tmds clk is 225000000 [ 28.637901] Support video mode: [ 28.637908] [email protected] [ 28.63791