jQuery 中的 Deferred 和 Promises

忘记这是在哪里做的笔记了。。。

js里异步函数大概有I/O函数(ajax、postMessage、请load、script load等)、计时函数(setTimeout、setInterval)等。

需要异步完成的场景:比如往DOM中注入节点,你必须等待节点注入后再操作这个节点,当大量节点注入的时间,时间往往很难把握。如果我们的代码依赖第三方api的数据,便无法获悉一个API响应的延迟时间,应用程序的其他部分可能会被阻塞,直到它返回结果。

CommonJS之Promises/A规范,通过规范API接口来简化异步编程,使我们的异步逻辑代码更易理解。遵循Promises/A规范的实现我们称之为Promise对象,promise对象有且仅有三种状态:unfulfilled(未完成)、fulfilled(已完成)、failed(失败/拒绝);初始创建的时候是unfulfilled(未完成)状态,状态只可以从unfulfilled(未完成)变成fulfilled(已完成),或者unfulfilled(未完成)变成failed(失败/拒绝)。状态一旦变成fulfiulled(已完成)或者failed(失败/拒绝),状态就不能在变了。

有个在程序中描述延时(或将来)概念的解决方案。主要的思想不是执行一个方法然后阻塞应用程序等待结果返回后再回调其他方法,而是返回一个Promise对象来满足未来监听。fulfilled状态和failed状态都可以被监听。

Promise通过实现一个then接口来返回Promise对象来注册回调:

then(fufiledHandler,errorHandler, progressHandler);

then接口用于监听一个promise的不同状态。fulfilledHandler用于监听fulfilled(已完成)状态,errorHandler用于监听failed(失败/拒绝)状态,progressHandler用于监听unfulfilled(未完成)状态。

一般认为,then接口返回的十一个新的promise对象,而不是原来的promise对象,这个新的promise对象可以理解为是原来promise对象的一个视图,它只包含原有promise对象的一组方法,这些方法只能观察原有Promise对象的状态,而无法更改deferred对象的内在状态。这样可以避免多个调用者之间的冲突,多个调用者可以通过改变新的Promise对象状态而不影响别的调用者。

另外,Promise提供了resolve(实现状态由未完成到已完成)和reject(实现状态由未完成到拒绝或失败)两个接口实现状态的转变。

几个遵循Promises/A规范的类库,when,q,rsvp.js,jQuery.Deferred等

Jquery的Deferred对象支持多个回调绑定多个任务,任务本身既可以是同步也可以是异步的。

举例说明:原来的ajax请求这么写


jQuery 中的 Deferred 和 Promises_第1张图片

从jq1.5开始,$ajax()返回的jqXHR对象实现了promise接口,使它拥有了Promise的所有属性,方法和行为。那么ajax可以这样写:


jQuery 中的 Deferred 和 Promises_第2张图片

或者这样:


jQuery 中的 Deferred 和 Promises_第3张图片

所有的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延迟对象解决或拒绝时,调用添加处理程序。


jQuery 中的 Deferred 和 Promises_第4张图片

$.deferred()方法作用是生成一个deferred对象

var deferred = $.deferred();

done()和fail()这两个方法都用来绑定回调函数。done()指定非同步操作成功后的回调函数,fail()指定失败后的回调函数。他们返回的是原有的deferred对象,因此可以采用链式写法,在后面在连接别的方法

resolve()和reject()这两个方法用来改变deferred对象的状态,resolve将状态改为非同步操作成功,reject()改为操作失败。一旦调用resolve(),就会依次执行fail()和then()方法指定的回调函数。

state方法用来返回deferred对象目前的状态,该方法的返回值有三个:pending:表示操作还没有完成;resolved表示操作成功;rejected表示操作失败。

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

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


jQuery 中的 Deferred 和 Promises_第5张图片


jQuery 中的 Deferred 和 Promises_第6张图片

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


jQuery 中的 Deferred 和 Promises_第7张图片


jQuery 中的 Deferred 和 Promises_第8张图片


jQuery 中的 Deferred 和 Promises_第9张图片

你可能感兴趣的:(jQuery 中的 Deferred 和 Promises)