美文网首页
deferred对象学习(下)(持续更新...)

deferred对象学习(下)(持续更新...)

作者: 小碗碗碗碗 | 来源:发表于2020-04-20 19:19 被阅读0次

前言:在上一次的deferred对象学习中,对于then的用法并没有展开讨论,同时上一篇文章中说到“$.when()的参数只能是deferred对象”这一说法有误。
特此在本篇文章中更正when用法,同时对then用法展开讨论。

一、Promise对象与Deferred对象的区别

Promise对象是ES6的异步操作解决方案,为异步操作提供统一接口。它起到代理作用,充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口,可以让异步操作写起来,就像在写同步操作的流程。
Promise的用法:
根据ES6的规定,Promise对象是一个构造函数,可以生成Promise实例,构造函数接受一个回调函数,该回调函数的参数有两个,resolve和reject,均由JS引擎提供,不用自己部署;生成实例后,可以用then方法分别指定resolved和rejected状态的回调函数。

function asyncFunc() {
    return new Promise(function(resolve, reject) {
        // some async task
        if (/*异步操作成功*/) {
            resolve(value);
        } else {
            reject(err);
        }
    });
}

asyncFunc().then(function(value) {
    //do something
}).catch(function(err) {
    //do something
});

Deferred对象是jQuery用来统一处理回调函数的一个解决方案,在1.5.0版本开始引入。jQuery中的Deferred对象实现了Promise,并且将resolve和reject方法暴露在了构造函数外面,使得改变promise对象的状态更为灵活。
deferred.promise()是返回了一个纯粹的promise对象,即不能在外部调用resolve和reject方法。
Deferred的用法:
jQuery的所有Ajax操作函数,默认返回的就是一个deferred对象

var dfd = $.Deferred();
dfd.then(function(value) {
    //do something
}).catch(function(err) {
    //do something
});

二、promise.then()与deferred.then()的区别

promise.then()
then()返回一个新的promise对象,如果then()指定的回调函数有返回值,该返回值会作为参数,传入后面的回调函数。
deferred.then()
在jQuery 1.8之前,then()只是.done().fail()写法的语法糖,两种写法是等价的。
在jQuery 1.8之后,then()返回一个新的deferred对象,而done()返回的是原有的deferred对象。如果then()指定的回调函数有返回值,该返回值会作为参数,传入后面的回调函数。

(注:由于Deferred对象实现了Promise,为了便于描述,后面直接统称为Promise对象)

.catch()与then()的rejected回调作用几乎一致。但是由于Promise的抛错具有冒泡性质,能够不断传递,这样就能够在下一个catch()中统一处理这些错误。同时catch()也能够捕获then()中抛出的错误,所以建议不要使用then()的rejected回调,而是统一使用catch()来处理错误
当状态已经改变为resolved后,即使抛出错误,也不会触发then()的错误回调或者catch()方法。
then() 和 catch() 都会返回一个新的Promise对象,可以链式调用。

三、使用then()解决回调地狱

首先,看下Promise实例的异步方法中传参promise和then()中返回promise有什么区别

// p1异步方法中返回p2
let p1 = new Promise ( (resolve, reject) => {
    resolve(p2)
} )
let p2 = new Promise ( ... )
p1.then(
    //todo
    alert('complete1');
).then(
    //todo
    alert('complete2');
)

// then()中返回promise
let p1 = new Promise ( (resolve, reject) => {
    resolve()
} )
let p2 = new Promise ( ... )
p1.then(
    alert('complete1');
    () => return p2
).then(
    //todo
    alert('complete2');
)

p1异步方法中传参p2
p1的状态取决于p2,如果p2为pending,p1将等待p2状态的改变,p2的状态一旦改变,p1将会立即执行自己对应的回调,即第一个then()中的方法。
由于then()本身就会返回一个新的promise,所以第二个then()中的方法针对的是第一个then()本身返回的promise。
if p2 resolved --> p1 resolved --> complete1

then()中返回promise
如果在第一个then()中的方法手动返回p4,那么第二个then()中的方法针对的是p4,这样就可以在p4中再次通过 resolve() 和 reject() 来改变状态,第二个then()中的方法将等待p4状态的改变。
p1 resolved --> complete1 --> if p2 resolved --> complete2

由此可见,当then中的方法返回的是Promise对象时,会针对返回的Promise对象继续进行等待。这样可以更好地解决前端中的回调地狱问题(即回调嵌套)
举例:A B C D 这4个返回Promise对象的方法,想要按顺序进行异步操作,即A执行完了再执行B,B执行完了再执行C…,则:
A.then(B).then(C).then(D)

四、$.when()的用法

如果向 $.when 传入一个延迟对象,那么会返回它的 Promise 对象,可以继续绑定 Promise 对象的其它方法,例如 defered.then。
当延迟对象已经被受理resolved或被拒绝rejected(通常是由创建延迟对象的最初代码执行的),那么就会调用适当的回调函数。
例如,由 jQuery.ajax 返回的 jqXHR 对象是一个延迟对象,可以向下面这样使用:

$.when( $.ajax("test.aspx") ).then(function(data, textStatus, jqXHR){
     alert( jqXHR.status ); // alerts 200
});

如果向 $.when 传入一个非延迟对象,那么它会被当作是一个被受理resolved的延迟对象,并且添加到上面的任何 doneCallbacks 都会被立刻执行,向 doneCallbacks 中传入的是原始的参数。
在这种情况下,设定的任何 failCallbacks 永远都不会被执行,因为延迟对象永远不会被拒绝rejected。例如:

$.when( { testing: 123 } ).done(
    function(x) { alert(x.testing); } /* alerts "123" */
);

相关文章

  • deferred对象学习(下)(持续更新...)

    前言:在上一次的deferred对象学习中,对于then的用法并没有展开讨论,同时上一篇文章中说到“$.when(...

  • Deferred对象

    Deferred对象 什么是Deferred对象?Deferred对象是从jQuery 1.5.0版本开始引入的一...

  • deferred对象学习(上)

    一、deferred对象是什么? defer:"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执...

  • jQuery.deferred详解

    deferred是什么? deferred 翻译为推迟,在jQuery 1.5中引入的Deferred对象是通过调...

  • deferred对象的方法

    (1)$.Deferred()生成一个deferred对象。(2)deferred.done()指定操作成功时的回...

  • deferred对象

    最近做项目,调用后端接口,需要等到2个ajax返回再执行另一个ajax,首先想到的是使用promise,但是考虑...

  • Deferred对象

    jQuery在1.5之后引进了Deferred对象,主要是对操作时间很长的方法回调提供一个简单、直观的解决方案。之...

  • Deferred对象

    jQuery.Deferred 对象 实例上的方法 一共14个 deferred.resolve(args) / ...

  • 学习promise

    概念学习 Promise 对象用于延迟(deferred) 计算和异步(asynchronous ) 计算.。一个...

  • jQuery-v2.0.3源码浅析05-when

    jQuery提供的when方法可以管理多个Deferred对象。打比方说如果你创建了多个Deferred对象,这个...

网友评论

      本文标题:deferred对象学习(下)(持续更新...)

      本文链接:https://www.haomeiwen.com/subject/awcdihtx.html