• Deferred


    上文中提到了Promise构造函数,就不得不提Deferred(延迟)对象了,其实,让Deferred对象得到推广的便是其在jQuery中的使用,本文就jQuery中对Deferred对象的使用进行探讨。

    1、Deferred的概念

    延迟对象,在jQuery的1.5引入,是通过调用jQuery.Deferred()方法创建一个可链式调用的工具对象。 它可以注册多个回调到回调队列, 调用回调队列,准备代替任何同步或异步函数的成功或失败状态。

    延迟对象是可链式调用的,类似于jQuery对象是可链接的方式,  但它有其自己的方法。 创建一个Deferred(延迟)对象后,你可以通过方法 直接从对象创建或者链式调用 或 保存对象的一个变量,调用该变量的一个或多个方法。

     jQuery.Deferred()基于Promises/A规范实现,因为jQuery本身的设计风格,jQuery.Deferred()并没有完全遵循Promises/A规范。
    jQuery在1.5版本中首次引入了Deferred。你可以通过jQuery.Deferred() 在未来某个时候 得到 ‘延时’返回值。 在此之前是无法单独使用的,Deferred作为对ajax模块较大重写的一部分添加进来。1.5和1.6版本包含Deferred功能,可以使$.ajax() 接收调用完成及请求出错的回调,但却存在严重的耦合。新版本的jQuery提供了一些增强的方式来管理回调,提供更加灵活的方式建立回调,而不用关心原始的回调是否已经触发。 jQuery的Deferred对象支持多个回调绑定多个任务,任务本身既可以是同步也可以是异步的。
    Deferred对象有三种状态,pending:未完成,resolved:已完成,rejected:未完成。(注:和Promise对象中的状态一模一样呢!)
     
    2、初试牛刀

     先看看$.Deferred是 什么?

    可以看出Deferred只是一个定义在jQuery上的普通方法,没有太多的信息,那我们调用一下试试。

    我们又可以看出,其实Deferred函数其实返回的是一个对象,这个对象也有always、catch、done、fail、notity、notifyWith、pipe、promise、progress、reject、rejectWith、resolve、resolveWith、state、then方法。

    Deferred有三个状态,pending:未完成,resolved:操作成功,rejected: 操作失败

    当deferred1对象调用resolved时,deferred1中的done方法会被调用,当deferred1对象调用rejected时,deferred1的fail方法会被调用,比如

    var deferred1 = $.Deferred();
    deferred1.done(function (data) {
        console.log('success: ',  data)
    })
    deferred1.fail(function (err) {
        console.log('err: ', err)
    })
    setTimeout(function(){
      deferred1.resolve('victory')
    },200)

    //输出success: victory

    3、Promise对象的方法

    我们接着聊notify和progress。

    progress()用来指定一个回调函数,当调用notify()方法时,该回调函数将执行。它的用意是提供一个接口,使得在非同步操作执行过程中,可以执行某些操作,比如定期返回进度条的进度。

    var userProgress = $.Deferred();
    var $profileFields = $("input");
    var totalFields = $profileFields.length;
    userProgress.progress(function (filledFields) {
        var pctComplete = (filledFields/totalFields)*100;
        $("#progress").html(pctComplete.toFixed(0));
    }); 
    userProgress.done(function () {
        $("#thanks").html("Thanks for completing your profile!").show();
    });
    $("input").on("change", function () {
        var filledFields = $profileFields.filter("[value!='']").length;
        userProgress.notify(filledFields);
        if (filledFields == totalFields) {
            userProgress.resolve();
        }
    });

    现在接着聊then方法,then方法接收三个回调函数,第一个参数是resolve时调用的回调函数,第二个参数是reject时调用的回调函数,第三个参数是progress()方法调用的回调函数。

    和谈Promise一样,现在我们也Deferred来封装一个getJSON函数,实现AJAX的例子

    var getJSON = function(url) {
        var deferred = $.Deferred();
       var client = new XMLHttpRequest(); client.open('GET', url); client.onreadystatechange = function(){ if (this.readyState !== 4) { return } if (this.status === 200) { deferred.resolve(this.response) } else { deferred.reject(new Error(this.statusText)) } } return deferred } getJSON('/db.json').then(function(json){ console.log('Result:', json) }, function(error){ console.log('error:', error) })

    4、Deferred中的promise对象

    大多数情况下,我们不想让用户从外部更改deferred对象的状态。这时,你可以在deferred对象的基础上,返回一个针对它的promise对象。我们可以把后者理解成,promise是deferred的只读版,或者更通俗地理解成promise是一个对将要完成的任务的承诺。

    你可以通过promise对象,为原始的deferred对象添加回调函数,查询它的状态,但是无法改变它的状态,也就是说promise对象不允许你调用resolve和reject方法。

    function getPromise(){
        return $.Deferred().promise();
    }
    try{
        getPromise().resolve("a");
    } catch(err) {
        console.log(err);
    }
    //会进入catch方法,显示TypeError {}

    jQuery的ajax() 方法返回的就是一个promise对象。

    
    
  • 相关阅读:
    【20220322】连岳摘抄
    【20220323】蓝天白云才是生活主调
    【ceph集群】构建rpm包
    C/C++ 将ShellCode注入进程内存
    算法:第一章:SnowFlake算法(分布式系统中生成唯一的ID的算法)SnowFlake每秒能够产生26万ID左右
    【设计一个刚好在一秒堆溢出的程序】
    模板引擎:第三章:使用Freemark做企业级SEO推广
    使用@Value给属性参数赋值
    解决:No active profile set, falling back to default profiles: default
    使用@ControllerAdvice进行全局异常处理关键代码
  • 原文地址:https://www.cnblogs.com/wbxjiayou/p/7205056.html
Copyright © 2020-2023  润新知