Deferred对象是由于 jQuery.Deferred 构造的,jQuery.Deferred
被实现啊简而言之工厂模式。

它们之所以来解决JS中的异步编程,它本 Common
Promise/A
规范。实现这规范的还有 when.js 和
dojo。

 

$.Deferred作为新特色首不成出现在本子1.5遭,这个本子采用Deferred又完全还写了Ajax模块。

$.Deferred于jQuery代码自身四处为利用,分别是promise方法、DOM
ready、Ajax模块、动画模块。

此间以本1.8.3剖析,由于1.7后$.Callbacks由Deferred中抽离出来了,目前版本的deferred.js代码不过150执,而真$.Deferred的兑现就出100尽左右。

 

$.extend给标示符$上挂了零星个方法,如下

jQuery.extend({
    Deferred: function( func ) {
        var tuples = [
                // action, add listener, listener list, final state
                [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
                [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
                [ "notify", "progress", jQuery.Callbacks("memory") ]
            ],
        ...

        // All done!
        return deferred;
    },
    // Deferred helper
    when: function( subordinate /* , ..., subordinateN */ ) {
        var i = 0,
            resolveValues = core_slice.call( arguments ),
            length = resolveValues.length,
            ....

        return deferred.promise();
    }
});

 

$.Deferred的实现

  1. 缔造三只$.Callbacks对象,分别表示成功,失败,处理中三种状态
  2. 创立了一个promise对象,具有state、always、then、primise方法
  3. 经过扩展primise对象生成最终之Deferred对象,返回该目标

 

$.when的实现

  1. 接受多少只目标,参数就一个且非Deferred对象将及时实施回调函数
  2. Deferred对象与非Deferred对象混杂时,对于非Deferred对象remaining减1
  3. Deferred对象总数 = 内部构建的Deferred对象 +
    所招参数中蕴藏的Deferred对象
  4. 所传参数中颇具Deferred对象在resolve时remaining减1,直到为0时(所有都resolve)执行回调

 

当下就算是$.Deferred和$.when的全体了,各个艺术与利用稍后介绍。

代码阅读着会意识then和when方法的贯彻最难以知晓,看多次,后谢回味无根本,非常巧妙。then内部会采取不同寻常的递归,when用到了计数,每次异步成功后减一,直到为0后代表一切异步操作成,这时才可实施回调。

 

上面提到Deferred里发3单$.Callbacks的实例,Deferred自身则围绕这三只目标开展双重胜似层次的架空。以下是Deferred对象的主导措施

  • done/fail/progress 是
    callbacks.add,将回调函数存入
  • resolve/reject/notify 是
    callbacks.fire,执行回调函数(或队列)

 

下面举一些示范看看哪些以Deferred对象。

 

一、done/resolve

function cb() {
    alert('success')
}
var deferred = $.Deferred()
deferred.done(cb)
setTimeout(function() {
    deferred.resolve()
}, 3000)

每当HTTP中意味后台返回成功状态(如200)时采取,即要成功后只是实行成功回调函数。

 

二、fail/reject

function cb() {
    alert('fail')
}
var deferred = $.Deferred()
deferred.fail(cb)
setTimeout(function() {
    deferred.reject()
}, 3000)

每当HTTP中意味着后台返回非成功状态时行使,即要失败后可实施破产回调函数。

 

三、progress/notify

function cb() {
    alert('progress')
}
var deferred = $.Deferred()
deferred.progress(cb)
setInterval(function() {
    deferred.notify()
}, 2000)

以HTTP中代表要过程中运用,即告过程遭到穿梭实践回调函数。这可用在文件及传时的loading百分比或快漫长。

 

季、链式操作

function fn1() {
    alert('success')
}
function fn2() {
    alert('fail')
}
function fn3() {
    alert('progress')
}
var deferred = $.Deferred()
deferred.done(fn1).fail(fn2).progress(fn3) // 链式操作
setTimeout(function() {
    deferred.resolve()
    //deferred.reject()
    //deferred.notify()
}, 3000)

诸如此类可以很便宜了丰富成功,失败,进度回调函数。

 

五,便利函数then,一涂鸦补充加事业有成,失败,进度回调函数

function fn1() {
    alert('success')
}
function fn2() {
    alert('fail')
}
function fn3() {
    alert('progress')
}
var deferred = $.Deferred()
deferred.then(fn1, fn2, fn3)

调用then后尚可以继续链式调用then添加多独不等回调函数,这个then也正是jQuery对 Common
Promise/A 的实现。

 

六、使用always方法为打响,失败状态添加同一个回调函数

var deferred = $.Deferred()
deferred.always(function() {
    var state = deferred.state() 
    if ( state === 'resolved') {
        alert('success')
    } else if (state === 'rejected') {
        alert('fail')
    }
})
setTimeout(function() {
    deferred.resolve()
    //deferred.reject()
}, 3000)

扭动调函数着得运用deferred.state方法取得异步过程遭到之最终状态,这里自己调用的凡deferred.resolve,因此最终之状态是resolved,表示成功。

 

七、when方法保证多只异步操作全部得逞后才回调

function fn1() {
    alert('done1')
}
function fn2() {
    alert('done2')
}
function fn3() {
    alert('all done')
}

var deferred1 = $.Deferred()
var deferred2 = $.Deferred()

deferred1.done(fn1)
deferred2.done(fn2)
$.when(deferred1, deferred2).done(fn3)

setTimeout(function() {
    deferred1.resolve()
    deferred2.resolve()
}, 3000)

先后弹来了done1、done2、all done。
如果setTimeout中来一个reject了,fn3将非见面给实践。

 

八、deferred.promise()方法返回只能添加回调的靶子,这个目标同$.Deferred()返回的目标不同,只能done/fail/progress,不克resolve/reject/notify。即只能调用callbacks.add,没有callbacks.fire。它是专业Deferred对象的阉割版。

 

 

出了Deferred,我们采取jQuery书写ajax的作风好这样了

$.ajax(url)
 .done(success)
 .progress(handling)
 .fail(fail)

 

好像与原先比较呢远非什么亮点,但它们还可以添加多单回调

$.ajax(url)
 .done(success1)
 .done(success2)
 .fail(fail2)
 .fail(fail2)

1.5事先的虽充分

 

倘多独请求完成后才好不容易成,1.5事先的凡无法缓解的,现在虽说足以据此$.when搞定

var ajax1 = $.ajax(url1)
var ajax2 = $.ajax(url2)
$.when(ajax1, ajax2).done(success)

 

若果项目面临产生一些异步问题不妨用用Derferred。

 

相关:

http://jimliu.net/?p=64

http://www.infoq.com/cn/news/2011/09/js-promise

http://www.erichynds.com/jquery/using-deferreds-in-jquery/

http://sitr.us/2012/07/31/promise-pipelines-in-javascript.html

http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html

 

相关文章

网站地图xml地图