二分之一

Just Jason's Blog

jQuery deferred对象API详解及DEMO

jQuery在1.5开始引入deferred(延迟),简单说,deferred对象就是jQuery的回调函数解决方案。

jQuery1.5中,Deferred对象提供一种方式来注册多个回调,添加到自已管理的回调队列中,调用适当的回调队列,并转达同步或异步函数的成功或失败状态。

deferred对象有三种执行状态:未完成(pending),已完成(resolved)和已失败(rejected)

API概览:

deferred object = {
    always(alwaysCallbacks [, alwaysCallbacks])
    //延迟对象不管成功或失败都最终会执行该方法

    done(doneCallbacks)
    //延迟对象成功完成后调用

    fail(failCallbacks)
    //延迟对象失败后调用

    isRejected()
    //确定延迟对象是否已失败

    isResolved()
    //确定延迟对象是否已成功

    notify( args )
    //用来触发一个自定义事件fireEvent

    notifyWith(context, [args])
    //跟notify一样,但可以指定上下文

    pipe([doneFilter] [, failFilter] [, progressFilter] )
    //jQuery的1.8,deferred.pipe()方法已经被淘汰。
    //用deferred.then()替代

    progress( progressCallbacks )
    //用来监控函数执行过程,进度处理程序,见:notify 方法

    reject([args])
    //使延迟对象的状态变为失败,对应的回调函数绑定方法为fail。

    rejectWith(context, [args])
    //使用方法与reject一样,但是可以指定上下文,使用可以参考 resolveWidth

    resolve([args])
    //使延迟对象的状态变为成功,对应的回调函数绑定方法为done。

    resolveWith(context, [args])
    //使用方法与resolve一样,但是可以指定上下文

    state()
    //查询延迟对象的状态,有三种:pending resolved rejected

    then(doneCallbacks, failCallbacks [, progressCallbacks])
    //一种缩写,用法与done,fail一样

    promise([target])
    //在原来的deferred对象上返回另一个deferred对象,
    //这个新的deferred对象屏蔽了改变状态的方法。
}

入门应用:

$.ajax("test.php")
.done(function(){ alert("成功了!"); })
.fail(function(){ alert("出错啦!"); });

从1.5开始,ajax对象不再返回xhr对象,而是deferred对象。通过.done执行成功回调,通过.fail执行失败回调。

1、$.when

返回一个Deferred对象,允许你为多个事件指定一个回调函数。

$.when($.ajax("test.php"),$.ajax("test2.php"))
.done(function(){ alert("成功了!"); })
.fail(function(){ alert("出错啦!"); });

这是一个与操作,只有test.php和test2.php都成功时才会执行done,否则执行fail;

2、resolve和reject的用法

var def = $.Deferred(); //创建deferred对象
var readConf = function(){
    fs.readFile('test.txt','utf-8', function(err, data) {
        if (err) {
           def.reject(); //改变deferred对象状态成失败
        } else {
           def.resolve(); //改变deferred对象状态成成功
        }
    });
    return def;  //返回
}

$.when(readConf())
.done(function(){ alert("成功了!"); })
.fail(function(){ alert("出错啦!"); });

3、promise用法

例2中,定义的def为全局变量,在作用域范围内,可以通过def.reject()或def.resolve()来改变其本身的状态,这样影响def的安全性,promise在原来的deferred对象上返回另一个deferred对象,这个新的deferred对象屏蔽了改变状态的方法。

var def = $.Deferred(); //创建deferred对象
var readConf = function(){
    fs.readFile('test.txt','utf-8', function(err, data) {
        if (err) {
           def.reject(); //改变deferred对象状态成失败
        } else {
           def.resolve(); //改变deferred对象状态成成功
        }
    });
    return def.promise();  //通过promise返回deferred对象,起到状态保护作用
}

$.when(readConf())
.done(function(){ alert("成功了!"); })
.fail(function(){ alert("出错啦!"); });

def.reject(); //更改无效

4、notify和progress用法

两者一般结合使用,有点自定义事件的意思。

var def = $.Deferred(); //创建deferred对象
var readConf = function(){
    def.notify('start');
    fs.readFile('test.txt','utf-8', function(err, data) {
        if (err) {
            def.reject(); //改变deferred对象状态成失败
            def.notify('fail');
        } else {
            def.resolve(); //改变deferred对象状态成成功
            def.notify('success');
        }
    });
    return def;
}

$.when(readConf())
.progress(function(_event){
    console.log(_event); //打印start,fail 或 start,success
    //_event是def.notify参数中指定的自定义事件名,是一个字符串
    //此处可以跟据不同事件进行相应的逻辑处理
});

5、then用法

$.when(readConf())
.then(function(){ alert("成功了!"); },function(){ alert("出错啦!"); });

最后修改时间:2014年9月10日星期三晚上7点47