jQuery使用Deferred对象执行异步操作

在JQuery 1.5之前,Ajax仅支持一个回调函数,但在JQuery的1.5版本中,引入了 Deferred对象,它和ES6的Promise对象长的有点像,jQuery的Deferred对象也有resolve、reject、then方法,还有done、fail、always......方法。jQuery就是用这个Deferred对象来注册异步操作的回调函数,修改并传递异步操作的状态。它允许注册多个回调函数,并且能传递任何同步或异步函数的执行状态:成功或失败。简单说, Deferred对象就是jQuery的回调函数解决方案,它解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口。

一、Promise 介绍

Promise: 给我一个承诺,我还你一个承诺

二、Promise构造函数 和 Deferred构造函数对比

 

三、Deferred 介绍

jQuery.Deferred()

创建一个新的Deferred对象的构造函数,可以带一个可选的函数参数,它会在构造完成后被调用。

jQuery.when()

通过该方式来执行基于一个或多个表示异步任务的对象上的回调函数

jQuery.ajax()

执行异步Ajax请求,返回实现了promise接口的jqXHR对象

deferred.then(resolveCallback,rejectCallback)

添加处理程序被调用时,递延对象得到解决或者拒绝的回调。

deferred.done()

当延迟成功时调用一个函数或者数组函数.

deferred.fail()

当延迟失败时调用一个函数或者数组函数.。

deferred.resolve(ARG1,ARG2,...)

调用Deferred对象注册的‘done’回调函数并传递参数

deferred.resolveWith(context,args)

调用Deferred对象注册的‘done’回调函数并传递参数和设置回调上下文

deferred.isResolved

确定一个Deferred对象是否已经解决。

deferred.reject(arg1,arg2,...)

调用Deferred对象注册的‘fail’回调函数并传递参数

deferred.rejectWith(context,args)

调用Deferred对象注册的‘fail’回调函数并传递参数和设置回调上下文

deferred.promise()

返回promise对象,这是一个伪造的deferred对象:它基于deferred并且不能改变状态所以可以被安全的传递

 四、案例

【1】分别通过Promise和Deferred去注册异步回调函数,通过setTimeout模拟异步

对比发现,由于jquery的Deferred对象本身就有resolve方法,所以我们在创建deferred对象的时候并未像promise那样传入了一个函数作为参数,在后面可以直接deferred.resolve()这样调用

    // Deferred
    function asyncFunc1() {
      var deferred = $.Deferred();
      //做一些异步操作
      setTimeout(function () {
        deferred.resolve('成功');
      }, 2000);
      return deferred;
    }
    asyncFunc1().then(function (data) {
      console.log(data) // 成功
    });


    // Promise
    function asyncFunc2() {
      var promise = new Promise(function (resolve, reject) {
        //做一些异步操作
        setTimeout(function () {
          resolve('成功');
        }, 2000);
      });
      return promise;
    }
    asyncFunc2().then(function (data) {
      console.log(data) // 成功
    });

【2】then的链式调用

    // Deferred
    function asyncFunc1() {
      var defered = $.Deferred();
      //做一些异步操作
      setTimeout(function () {
        defered.resolve('成功');
      }, 2000);
      return defered;
    }

    asyncFunc1().then(function (data) {
      console.log(data) 
      return asyncFunc2() 
    }).then(function (data) {
      console.log(data); 
      return asyncFunc3(); 
    }).then(function (data) {
      console.log(data); 
    });

【3】then方法的参数,done与fail语法糖

在Promise中then(onfulfilled,onrejected)方法中有两个参数,两个参数都是函数,第一个参数执行的是resolve()方法(即异步成功后的回调方法),第二参数执行的是reject()方法(即异步失败后的回调方法)(第二个参数可选)。在Deferred中进行了增强,还可以接受第三个参数,就是在pending状态时的回调 。除此之外,jquery还增加了两个语法糖方法,done和fail,分别用来指定执行完成和执行失败的回调

    // Deferred
    function asyncFunc1() {
      var defered = $.Deferred();
      //做一些异步操作
      setTimeout(function () {
        if ( /*异步操作成功*/ ) {
          defered.resolve(success)
        } else {
          defered.reject(error)
        }
      }, 2000);
      return defered;
    }

    asyncFunc1.then(function (success) {
      // 异步操作成功在这里执行
      // 对应于上面的resolve(success)方法
    }, function (error) {
      // 异步操作失败在这里执行
      // 对应于上面的reject(error)方法
    });

    // 还可以写成这样 (推荐使用这种写法)
    asyncFunc1.done(function (success) {
      // 异步操作成功在这里执行
      // 对应于上面的resolve(success)方法
    }).fail(function (error) {
      // 异步操作失败在这里执行
      // 对应于上面的reject(error)方法
    });

【4】always的用法

Deferred对象上还有一个always方法,不论执行完成还是执行失败,always都会执行,有点类似promise中的finally方法

    asyncFunc1.done(function (success) {
      // 异步操作成功在这里执行
      // 对应于上面的resolve(success)方法
    }).fail(function (error) {
      // 异步操作失败在这里执行
      // 对应于上面的reject(error)方法
    }).always(function() {
      // 都会执行
    })

五、$.when方法

 jquery中,还有一个when方法来实现Promise,与Promise中的all方法功能类似,Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作都执行完毕后才执行回调,只要其中一个异步操作返回的状态为rejected那么Promise.all()返回的Promise即为rejected状态。

两者的区别是,接受的参数不同,Promise.all方法接受一个数组作为参数,但每个参数必须是一个Promise实例,而$.when方法接受多个Deferred对象,用逗号隔开

    // $.when()
    $.when(asyncFunc1(), asyncFunc2(), asyncFunc3())
      .then(function (data1, data2, data3) {
        console.log('全部执行完成');
        console.log(data1, data2, data3);
      }).fail(function (error) {

      })

    // Promise.all()
    Promise.all([asyncFunc1(), asyncFunc2(), asyncFunc3()])
      .then((success) => {
        console.log(success)
      }).catch((error) => {
        console.log(error)
      })

当需要传入不确定数量的Deferred对象参数到$.when时,我们可以使用apply方法传入数组作为参数去解决这个问题

    function asyncFunc1() {
      var defered = $.Deferred();
      setTimeout(function () {
        defered.resolve('成功')
      }, 200)
      return defered
    }

    // 生成5个异步回调函数,添加到数组
    let arr = []
    for (let i = 0; i < 5; i++) {
      arr.push(asyncFunc1())
    }

    // 传入数组作为参数
    $.when.apply(this, arr)
      .then(function (...args) {
        // 获取执行结果数据

        // es6
        console.log(args) 
        
        // es5
        var res=[].slice.apply(arguments)
        console.log(res)
        
      })

文章每周持续更新,可以微信搜索「 前端大集锦 」第一时间阅读,回复【视频】【书籍】领取200G视频资料和30本PDF书籍资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
jQuery 中的 Deferred 对象提供了一种优雅的方式来处理异步操作,它可以让我们更方便地控制异步操作的状态和执行顺序。下面是 Deferred 对象的常用方法: 1. $.Deferred():创建一个 Deferred 对象。 2. deferred.done():当 Deferred 对象的状态变为已完成时,调用该方法注册的回调函数。 3. deferred.fail():当 Deferred 对象的状态变为已失败时,调用该方法注册的回调函数。 4. deferred.always():无论 Deferred 对象的状态是已完成还是已失败,都调用该方法注册的回调函数。 5. deferred.then():当 Deferred 对象的状态变化时,调用该方法注册的回调函数。它可以接受两个参数,第一个参数是已完成状态的回调函数,第二个参数是已失败状态的回调函数。 6. deferred.promise():返回一个 Promise 对象,该对象可以被传递给其他函数或者方法,但只能调用 then()、catch() 和 finally() 方法,不能改变 Deferred 对象的状态。 下面是一个使用 Deferred 对象的示例代码: ```javascript function asyncAction() { var defer = $.Deferred(); setTimeout(function() { defer.resolve("Async Action Completed!"); }, 2000); return defer.promise(); } var promise = asyncAction(); promise.then(function(data) { console.log(data); }).fail(function() { console.log("Async Action Failed!"); }).always(function() { console.log("Async Action Done!"); }); ``` 在这个例子中,我们定义了一个 asyncAction() 函数,它返回一个 Deferred 对象。在该函数内部,我们使用 setTimeout() 函数模拟一个异步操作,并在两秒后调用 resolve() 方法,将 Deferred 对象的状态设置为已完成。然后我们使用 promise 变量保存该 Deferred 对象Promise 对象,并使用 then()、fail() 和 always() 方法注册回调函数。在 then() 方法中,输出异步操作完成的信息;在 fail() 方法中,输出异步操作失败的信息;在 always() 方法中,输出异步操作完成的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@Demi

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值