返回顶部
首页 > 资讯 > 前端开发 > html >jQuery 1.5中deferred对象如何使用
  • 780
分享到

jQuery 1.5中deferred对象如何使用

2024-04-02 19:04:59 780人浏览 薄情痞子
摘要

Jquery 1.5中deferred对象如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。jQuery1.5中新增的De

Jquery 1.5中deferred对象如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

jQuery1.5中新增的Deferreds对象,可以将任务完成的处理方式与任务本身解耦合。这在javascript社区没什么新意,因为Mochikit和Dojo两个js框架已经实现了这个特性很长一段时间了。但是随着Julian Aubourg对jQuery1.5中ajax模块的重写,deferreds理所当然成为了内部的实现逻辑。使用deferreds对象,多个回调函数可以被绑定在任务完成时执行,甚至可以在任务完成后绑定这些回调函数。这些任务可以是异步的,也可以是同步的。

更重要的是,deferreds已经作为$.ajax()的内部实现,所以你可以在调用AJAX时自动获取deferreds带来的遍历。比如我们可以这样绑定回调函数:

// $.get, 异步的AJAX请求  var req = $.get('foo.htm').success(function (response) {      // AJAX成功后的处理函数  }).error(function () {      // AJAX失败后处理函数  });     // 这个函数有可能在AJAX结束前调用  doSomethingAwesome();     // 添加另外一个AJAX回调函数,此时AJAX或许已经结束,或许还没有结束  // 由于$.ajax内置了deferred的支持,所以我们可以这样写  req.success(function (response) {      // 这个函数会在AJAX结束后被调用,或者立即被调用如果AJAX已经结束  });

我们不再被限制到只有一个成功,失败或者完成的回调函数了。相反这些随时被添加的回调函数被放置在一个先进先出的队列中。

从上面例子看出,回调函数可以被附加到AJAX请求中(任何可观察的任务observable task),甚至在AJAX请求已经结束。对于代码的组织是很好的,我们再也不用写很长的回调函数了。这就像$.queue()遇到了pub/sub(发布订阅机制,一般用在基于事件处理的模型中).

更深入一些,想象这样一个场景,在一些并发的AJAX请求全部结束之后执行一个回调函数。我可以方便的通过jQuery的函数$.when()来完成:

function doAjax() {      return $.get('foo.htm');  }     function doMoreAjax() {      return $.get('bar.htm');  }     $.when(doAjax(), doMoreAjax()).then(function () {      console.log('I fire once BOTH ajax requests have completed!');  }).fail(function () {      console.log('I fire if one or more requests failed.');  });

在jsFiddle中打开示例 Http://jsfiddle.net/ehynds/Mrqf8/

上面的示例能够正常运行,这要归功于每个jQuery的AJAX方法返回值都包含一个promise函数,用来跟踪异步请求。Promise函数的返回值是deferred对象的一个只读视图。(The promise is a read-only view into the result of the task.)Deferreds通过检测对象中是否存在promise()函数来判断当前对象是否可观察。$.when()会等待所有的AJAX请求结束,然后调用通过 .then(), .fail()注册的回调函数(具体调用哪些回调函数取决于任务的结束状态)。这些回调函数会按照他们的注册顺序执行。

更好的是,$.when()接受函数或者函数的数组为参数(译者注:这点不大对,$.when接受一个或多个deferred对象,或者原生的JS对象。注意不能以函数数组为参数),这样你就可以随意组合这些异步任务。

$.ajax()返回一个对象,这个对象关联一些deferred函数,比如promise(), then(), success(), error()。然而你不能操作原始的deferred对象,只有promise()函数(译者注:还记得刚才提到的promise是只读视图),以及可以检测deferred状态的isRejected() 以及isResolved()函数。

但是为什么不返回deferred对象呢?如果返回了完整的deferred对象,那么我们就拥有更多的控制,或许可以随意的触发(译者注:我把resolve翻译成触发,就是触发所有注册到deferred对象上的回调函数)deferred对象,从而导致所有回调函数在AJAX请求结束之前执行。因此,为了避免不期望的触发deferred的风险,我们应该只返回dfd.promise().(Therefore, to avoid potentially breaking the whole paradigm, only return the dfd.promise().)(译者注:如果你很迷惑上面几段话的确切意思,没关系,我随后会写一篇文章深层次分析其中原因:http:/cnblogs.com/sanshi/)

注册回调函数(Registering Callbacks)

上面的例子中,我们使用then(), success(), fail()方法来注册回调函数,其实还有更多的方法可以使用,特别在处理AJAX请求时。具体使用哪种方式取决于你对结果状态的关注。

所有deferred对象都有的函数 (AJAX, $.when 或者手工创建的deferred对象):

.then( doneCallbacks, failedCallbacks )  .done( doneCallbacks )  .fail( failCallbacks )

AJAX对象包含3个额外的方法,其中两个会映射到上面提到的方法。这些方法主要是为了兼容以前的代码:

// "success" 和 "error" 会分别映射到 "done" and "fail" 两个方法  .success( doneCallbacks )  .error( failCallbacks )

你也可以注册一个complete的回调函数,它会在请求结束后调用,而不管这个请求是成功或者失败。不像success或者error函数,complete函数其实是一个单独的deferred对象的done函数别名。这个在$.ajax()内部创建的deferred对象,会在AJAX结束后触发回调函数(resolve)。

.complete( completeCallbacks )

因此,下面的3个例子是等价的(在AJAX的上下文中,success看起来比done函数会舒服点,对么?)(译者注:其实是因为我们熟悉以前的AJAX调用方式,先入为主罢了,或者叫思维定势):

$.get("/foo/").done( fn );  // 等价于:  $.get("/foo/").success( fn );  // 等价于:  $.get("/foo/", fn );

创建自己的deferred对象(Creating your own Deferred)

我们知道$.ajax和$.when在内部实现了deferred接口,不过我们也可以手工创建deferred对象:

function getData() {      return $.get('/foo/');  }     function showDiv() {      var dfd = $.Deferred();      $('#foo').fadeIn(1000, dfd.resolve);      return dfd.promise();  }     $.when(getData(), showDiv()).then(function (ajaxResult) {      console.log('The animation AND the AJAX request are both done!');      // 'ajaxResult'是服务器端返回(译者注:也就是getData中AJAX的结果)  });

在jsFiddle中打开示例 http://jsfiddle.net/ehynds/JSw5y/

在showDiv()中,我们创建了一个deferred对象,执行了一段动画,然后返回promise。这个deferred对象会在fadeIn()结束后被触发(resolved)。在这个promise返回和deferred对象(注意:这里的deferred指的是$.when创建的对象,而非showDiv()返回的对象)触发的中间,一个then()回调函数会被注册。这个回调函数会在两个异步的任务全部结束后执行。

getData()返回一个对象(译者注:其实是jQuery封装的XMLHttpRequest对象)拥有promise方法,这就允许$.when()监视本次AJAX请求的结束。The manually steps we took to return a promise in showDiv() is handled for us internally by $.ajax() and $.when().

1/15/2011: Julian在评论中指出,上面的语法可以被简化为$.Deferred(fn).promise()。因此下面的两端代码是等价的:

function showDiv() {      var dfd = $.Deferred();      $('#foo').fadeIn(1000, dfd.resolve);      return dfd.promise();  }  // 等价于:  function showDiv() {      return $.Deferred(function (dfd) {          $('#foo').fadeIn(1000, dfd.resolve);      }).promise();  }

为自定义的deferred对象添加回调函数(Defer your Deferreds)

我们可以更进一步,为getData()和showDiv()分别注册回调函数,如同我们在$.then()中注册回调函数一样。(译者注:下面的段落内容重复,说的都是一个意思,就不翻译了,看代码吧)

function getData() {      return $.get('/foo/').success(function () {          console.log('Fires after the AJAX request succeeds');      });  }     function showDiv() {      return $.Deferred(function (dfd) {          // 译者注:这段代码是原文没有的,但是在jsFiddle中出现。          // 我觉得这是作者的原意,为自定义的deferred函数注册回调函数          dfd.done(function () {              console.log('Fires after the animation succeeds');          });          $('#foo').fadeIn(1000, dfd.resolve);      }).promise();  }     $.when(getData(), showDiv()).then(function (ajaxResult) {      console.log('Fires after BOTH showDiv() AND the AJAX request succeed!');      // 'ajaxResult'是服务器返回结果  });

在jsFiddle中打开示例 http://jsfiddle.net/ehynds/W3cQc/

链式代码(Chaining Hotness)

Deferred的回调函数可以链式调用,只要函数返回的是deferred对象(译者注:dfd.promise()返回的是只读的deferred对象)。这是一个实际的代码 (via @ajpiano!)

function saveContact(row) {      var fORM = $.tmpl(templates["contact-form"]),          valid = true,          messages = [],          dfd = $.Deferred();             if (!valid) {          dfd.resolve({              success: false,              errors: messages          });      } else {          form.ajaxSubmit({              dataType: "JSON",              success: dfd.resolve,              error: dfd.reject          });      }         return dfd.promise();  };     saveContact(row).then(function (response) {      if (response.success) {          // 客户端验证通过,并且保存数据成功      } else {          // 客户端验证失败          // 输出错误信息      }  }).fail(function (err) {      // AJAX请求失败  });

saveContact()函数首先验证表单数据的有效性,然后把有效性状态保存在变量valid中。如果验证失败,直接deferred会被触发(把一个包含success状态码和错误信息的JS对象作为参数传递给回调函数)。如果验证通过,则向服务器提交数据,在AJAX成功完成后触发deferred对象。fail()会处理404, 500等可以阻止AJAX请求成功完成的HTTP状态码。

不可观察的任务(Non-observable Tasks)

Deferreds对于解耦任务与任务处理函数时非常有用,而不管是异步任务或者同步任务。一个任务可能会返回promise,但也可以返回字符串,对象或者其他类型。

在这个例子中,当“Lanch Application”链接被***点击时,一个AJAX请求会发送到服务器并返回当前时间戳。然后这个时间戳会被保存到这个链接的data缓存中。当这个链接再次被点击时,只是简单的从缓存中取出这个时间戳返回,而不会发出AJAX请求。

function startTask(element) {      var timestamp = $.data(element, 'timestamp');         if (timestamp) {          return timestamp;      } else {          return $.get('/start-task/').success(function (timestamp) {              $.data(element, 'timestamp', timestamp);          });      }  }     $('#launchApplication').bind('click', function (event) {      event.preventDefault();         $.when(startTask(this)).done(function (timestamp) {          $('#status').html('<p>You first started this task on: ' + timestamp + '</p>');      });         loadApplication();  });

当$.when()发现它的***个参数没有promise函数(因此不可观察),它就会创建一个新的deferred对象,触发deferred对象,并返回promise只读对象。因此,任意不可观察的任务也能传递到$.when()中。

需要注意的一个问题是,如果一个对象自身拥有promise函数,则这个对象将不能作为deferred对象。jQuery判断一个对象是否deferred,是通过查看它是否有promise函数来决定的,但是jQuery并不会检查这个promise是否真的返回一个可用的对象。因此下面的代码将会出错:

var obj = {      promise: function () {          // do something      }  };     $.when(obj).then(fn);

结论(Conclusion)

Deferreds提出了一种新的健壮的方式来处理异步任务。和传统的将代码组织到一个回调函数中不同,新的deferred对象允许我们在任何时候(甚至在任务结束后)绑定多个回调函数,而这些回调函数会以先进先出的方式被调用。这篇文章中的信息可能比较难以消化,不过一旦你掌握了deferred对象的使用,你会发现组织异步执行的代码将会非常容易。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网html频道,感谢您对编程网的支持。

--结束END--

本文标题: jQuery 1.5中deferred对象如何使用

本文链接: https://lsjlt.com/news/73747.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • jQuery 1.5中deferred对象如何使用
    jQuery 1.5中deferred对象如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。jQuery1.5中新增的De...
    99+
    2024-04-02
  • html中dom对象如何转为jquery对象
    这篇文章主要介绍了html中dom对象如何转为jquery对象,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。转换方法:对于已经是一个DOM对象,只需要用“$()”把DOM对象...
    99+
    2023-06-15
  • 如何用jQuery 2.0.3源码分析Deferred
    本篇文章给大家分享的是有关如何用jQuery 2.0.3源码分析Deferred,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。构建Deferr...
    99+
    2024-04-02
  • jQuery中Deferred的deferred.promise()方法怎么使用
    这篇文章主要讲解了“jQuery中Deferred的deferred.promise()方法怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“jQuery中Deferred的deferr...
    99+
    2023-07-04
  • js对象如何转换jquery对象
    这篇文章将为大家详细讲解有关js对象如何转换jquery对象,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 js对象转换jquery对象的方法...
    99+
    2024-04-02
  • jquery对象如何转为js对象
    这篇文章主要介绍“jquery对象如何转为js对象”,在日常操作中,相信很多人在jquery对象如何转为js对象问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”jquery对象...
    99+
    2024-04-02
  • jQuery中如何使用$.extend方法来扩展JSON对象
    这篇文章给大家分享的是有关jQuery中如何使用$.extend方法来扩展JSON对象的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。$.extend方法可以扩展JSON对象,用一...
    99+
    2024-04-02
  • jquery对象如何转化为dom对象
    这篇文章主要介绍了jquery对象如何转化为dom对象的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇jquery对象如何转化为dom对象文章都会有所收获,下面我们一起来看看吧。...
    99+
    2024-04-02
  • jquery对象与dom对象如何转换
    这篇文章主要介绍了jquery对象与dom对象如何转换的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇jquery对象与dom对象如何转换文章都会有所收获,下面我们一起来看看吧。...
    99+
    2024-04-02
  • jQuery对象和DOM对象如何转换
    jQuery对象和DOM对象如何转换?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。jquery是什么jquery是一个简洁而快速的JavaScript库,它具有...
    99+
    2023-06-14
  • jquery对象如何转为html dom对象
    这篇文章主要介绍了jquery对象如何转为html dom对象,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。转换方法:1、jQuery对象是一个数据对象时,可以通过“[ind...
    99+
    2023-06-15
  • jQuery如何克隆对象
    小编给大家分享一下jQuery如何克隆对象,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!克隆对象$(document).read...
    99+
    2024-04-02
  • jquery如何定义对象
    在jquery中定义对象的方法:1.新建html项目,引入jquery;2.使用{}定义对象;3.使用eval方法为对象添加属性;具体步骤如下:首先,新建一个html项目,并在项目中引入jquery;<script type=&quo...
    99+
    2024-04-02
  • jquery如何合并对象
    使用jquery合并对象的方法:1.新建html项目,引入jquery;2.创建测试对象,并赋值;3.使用$.extend()方法合并对象;具体步骤如下:首先,新建一个html项目,并在项目中引入jquery;<script type...
    99+
    2024-04-02
  • 如何将JavaScript对象转成jQuery对象数组对象
    JavaScript 是一种高级的动态编程语言,非常流行。它使得网页在不需要刷新页面的情况下变得更加动态和交互性。然而,当 JavaScript 开发变得越来越复杂,常常需要处理大量的 HTML 元素,这时候就需要用到 jQuery。jQu...
    99+
    2023-05-14
  • Python的Twisted框架中使用Deferred对象来管理回调函数
    首先抛出我们在讨论使用回调编程时的一些观点: 激活errback是非常重要的。由于errback的功能与except块相同,因此用户需要确保它们的存在。他们并不是可选项,而是必选项。 不在错误的时...
    99+
    2022-06-04
    回调 函数 框架
  • jQuery中如何将$引用的对象映射回原始的对象
    本文小编为大家详细介绍“jQuery中如何将$引用的对象映射回原始的对象”,内容详细,步骤清晰,细节处理妥当,希望这篇“jQuery中如何将$引用的对象映射回原始的对象”文章能帮助大家解决疑惑,下面跟着小编...
    99+
    2024-04-02
  • 如何将dom对象转换成jquery对象
    这篇文章主要介绍“如何将dom对象转换成jquery对象”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何将dom对象转换成jquery对象”文章能帮助大家解决问题...
    99+
    2024-04-02
  • JavaScript中对象如何使用
    这期内容当中小编将会给大家带来有关JavaScript中对象如何使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。 介绍JavaScript 中,对象是 键/值...
    99+
    2024-04-02
  • jquery如何定义json对象
    在jquery中定义json对象的方法:1.新建html项目,引入jquery;2.使用json字符串定义json对象;3.使用JSON.parse方法解析json对象;具体步骤如下:首先,新建一个html项目,并在项目中引入jquery;...
    99+
    2024-04-02
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作