jQuery Deferred和Promise创建响应式应用程序详细介绍

这篇文章,我们一起探索一下 JavaScript 中的 Deferred 和 Promise 的概念,它们是 JavaScript 工具包(如Dojo和MochiKit)中非常重要的一个功能,最近也首次亮相于 流行的 JavaScript 库 jQuery(已经是1.5版本的事情了)。 Deferred 提供了一个抽象的非阻塞的解决方案(如 Ajax 请求的响应),它创建一个 “promise” 对象,其目的是在未来某个时间点返回一个响应。如果您之前没有接触过 “promise”,我们将会在下面做详细介绍。

抽象来说,deferreds 可以理解为表示需要长时间才能完成的耗时操作的一种方式,相比于阻塞式函数它们是异步的,而不是阻塞应用程序等待其完成然后返回结果。deferred对 象会立即返回,然后你可以把回调函数绑定到deferred对象上,它们会在异步处理完成后被调用。

Promise
  你可能已经阅读过一些关于promise和deferreds实现细节的资料。在本章节中,我们大致介绍下promise如何工作,这些在几乎所有的支持deferreds的javascript框架中都是适用的。

  一般情况下,promise作为一个模型,提供了一个在软件工程中描述延时(或将来)概念的解决方案。它背后的思想我们已经介绍过:不是执行一个方法然后阻塞应用程序等待结果返回,而是返回一个promise对象来满足未来值。

  举一个例子会有助于理解,假设你正在建设一个web应用程序, 它很大程度上依赖第三方api的数据。那么就会面临一个共同的问题:我们无法获悉一个API响应的延迟时间,应用程序的其他部分可能会被阻塞,直到它返回 结果。Deferreds 对这个问题提供了一个更好的解决方案,它是非阻塞的,并且与代码完全解耦 。

  Promise/A提议'定义了一个'then‘方法来注册回调,当处理函数返回结果时回调会执行。它返回一个promise的伪代码看起来是这样的:

复制代码 代码如下:


promise = callToAPI( arg1, arg2, ...);
promise.then(function( futureValue ) {
/* handle futureValue */
});
promise.then(function( futureValue ) {
/* do something else */
});


此外,promise回调会在处于以下两种不同的状态下执行:

•resolved:在这种情况下,数据是可用
•rejected:在这种情况下,出现了错误,没有可用的值
  幸运的是,'then'方法接受两个参数:一个用于promise得到了解决(resolved),另一个用于promise拒绝(rejected)。让我们回到伪代码:

复制代码 代码如下:


promise.then( function( futureValue ) {
/* we got a value */
} , function() {
/* something went wrong */
} );


在某些情况下,我们需要获得多个返回结果后,再继续执行应用程序(例如,在用户可以选择他们感兴趣的选项前,显示一组动态的选项)。这种情况下,'when'方法可以用来解决所有的promise都满足后才能继续执行的场景。

复制代码 代码如下:


when(
promise1,
promise2,
...
).then(function( futureValue1, futureValue2, ... ) {
/* all promises have completed and are resolved */
});


一个很好的例子是这样一个场景,你可能同时有多个正在运行的动画。 如果不跟踪每个动画执行完成后的回调,很难做到在动画完成后执行下一步任务。然而使用promise和‘when'方式却可以很直截了当的表示: 一旦动画执行完成,就可以执行下一步任务。最终的结果是我们可以可以简单的用一个回调来解决多个动画执行结果的等待问题。 例如:

复制代码 代码如下:


when( function(){
/* animation 1 */
/* return promise 1 */
}, function(){
/* animation 2 */
/* return promise 2 */
} ).then(function(){
/* once both animations have completed we can then run our additional logic */
});


这意味着,基本上可以用非阻塞的逻辑方式编写代码并异步执行。 而不是直接将回调传递给函数,这可能会导致紧耦合的接口,通过promise模式可以很容易区分同步和异步的概念。

  在下一节中,我们将着眼于jQuery实现的deferreds,你可能会发现它明显比现在所看到的promise模式要简单。

jQuery的Deferreds
  jQuery在1.5版本中首次引入了deferreds。它 所实现的方法与我们之前描述的抽象的概念没有大的差别。原则上,你获得了在未来某个时候得到‘延时'返回值的能力。在此之前是无法单独使用的。 Deferreds 作为对ajax模块较大重写的一部分添加进来,它遵循了CommonJS的promise/ A设计。1.5和先前的版本包含deferred功能,可以使$.ajax() 接收调用完成及请求出错的回调,但却存在严重的耦合。开发人员通常会使用其他库或工具包来处理延迟任务。新版本的jQuery提供了一些增强的方式来管理 回调,提供更加灵活的方式建立回调,而不用关心原始的回调是否已经触发。 同时值得注意的是,jQuery的递延对象支持多个回调绑定多个任务,任务本身可以既可以是同步也可以是异步的。

  您可以浏览下表中的递延功能,有助于了解哪些功能是你需要的:
jQuery.Deferred()   创建一个新的Deferred对象的构造函数,可以带一个可选的函数参数,它会在构造完成后被调用。  
jQuery.when()   通过该方式来执行基于一个或多个表示异步任务的对象上的回调函数  
jQuery.ajax()   执行异步Ajax请求,返回实现了promise接口的jqXHR对象  
deferred.then(resolveCallback,rejectCallback)   添加处理程序被调用时,递延对象得到解决或者拒绝的回调。  
deferred.done()  

当延迟成功时调用一个函数或者数组函数.

 
deferred.fail()  

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wddwds.html