【转载】jQuery Promise 实现 Deferred

转载地址不详,总之来自网络

Deferred 对象解决 JS 异步编程,实现 Common Promise/A 规范。deferred 对象是 jQuery 回调函数的解决方案。

传统写法

$.ajax({
    url : "test.html",
    success : function() {
        alert("哈哈,成功了!");
    },
    error : function() {
        alert("出错啦!");
    }
});

新的写法

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

好处1:多个回调

$.ajax("test.html").done(function() {
    alert("哈哈,成功了!");
}).fail(function() {
    alert("出错啦!");
}).done(function() {
    alert("第二个回调函数!");
});

好处2:多个操作都成功

# 两个操作:$.ajax("test1.html") 和 $.ajax("test2.html"),都成功则调用 done,否则调用 fail

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

$.when($.ajax("/page1.php"), $.ajax("/page2.php"))
  .then(myFunc, myFailure);

普通函数也可以使用 deferred 对象

并没有返回 deferred 对象,而是返回 promise() 对象,好处是不能在外部改变 deferred 的状态,即:调用 resolve 或 reject

$.when() 的参数必须是 deferred 对象

deferred 对象最大优点:把这一套回调函数接口,从 ajax 操作扩展到所有操作

deferred 对象三种执行状态
* 未完成
* 已完成
* 已失败

  • 如果执行状态是已完成(resolved),deferred 对象立刻调用 done() 方法指定的回调函数
  • 如果执行状态是已失败,调用 fail() 方法指定的回调函数
  • 如果执行状态是未完成,则继续等待,或调用 progress() 方法指定的回调函数,jQuery1.7 添加

ajax 操作,deferred 对象根据返回结果,自动改变自身的执行状态

在普通函数 wait() 中,执行状态必须由程序员手动指定
* dtd.resolve(),将 dtd 对象的执行状态从未完成改为已完成,触发 done() 方法
* dtd.reject(),将 dtd 对象的执行状态从未完成改为已失败,触发 fail() 方法

var wait = function() {
    // 函数内部新建 Deferred 对象
    var dtd = $.Deferred();
    var tasks = function() {
        alert("执行完毕!");

        // 改变 Deferred 对象的执行状态
        dtd.resolve();
    };

    setTimeout(tasks, 5000);

    // 返回 promise 对象
    return dtd.promise();
};

$.when(wait()).done(function() {
    alert("哈哈,成功了!");
}).fail(function() {
    alert("出错啦!");
});
  • $.Deferred() 生成一个 deferred 对象
  • deferred.done() 指定操作成功时的回调函数
  • deferred.fail() 指定操作失败时的回调函数
  • deferred.promise() 没有参数时,返回一个新 deferred 对象,该对象运行状态无法改变;接受参数时,作用为在参数对象上部署 deferred 接口
  • deferred.resolve() 手动改变 deferred 对象的运行状态为”已完成”,从而立即触发 done() 方法
  • deferred.reject() 与 deferred.resolve() 正好相反,调用后将 deferred 对象运行状态变为”已失败”,从而立即触发 fail() 方法
  • $.when() 为多个操作指定回调函数

deferred.then()

# 有时为省事,可把 done() 和 fail() 合在一起写,就是 then() 方法
$.when($.ajax( "/main.php" )).then(successFunc, failureFunc);

deferred.always()

# 指定回调函数,不管调用 deferred.resolve() 还是 deferred.reject(),最后总执行
$.ajax( "test.html" ).always( function() { alert("已执行!");} );

done/resolve

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

fail/reject

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

progress/notify

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

不断调用,如:进度条更新进度值

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)

串2

function fn1() {
    alert('success')
}
function fn2() {
    alert('fail')
}
function fn3() {
    alert('progress')
}
var deferred = $.Deferred()
// Common Promise/A 的实现
deferred.then(fn1, fn2, fn3)

不管成功,失败,总是 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)

全部成功才

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。有一个 reject,fn3 不被执行

deferred.promise() 返回只能添加回调的对象,对象与 $.Deferred() 返回对象不同,只能 done/fail/progress,不能 resolve/reject/notify。
即只能 callbacks.add,没 callbacks.fire,是正统 Deferred 对象的阉割版。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值