• 前端程序,以提高旅游(九)----延迟对象


                近日,内部推荐计划,当进入项目主页。。依照以往的习惯,应该将调用接口后运行的代码。放入ajax请求success内运行。这样当然能够。可是代码组织和可读性都没有那么高。

    通过查看Jquery官网api发现了deferred object(延迟对象)这个概念。

       一、API文档的翻译:

       延迟对象,在jquery1.5被引入。是调用jQuery.Deferred()方法生成的一个链式功用对象。它能够注冊多个回调到回调队列。提取回调队列,传递不论什么异步或同步函数的成功或失败状态。
       延迟对象是一个链式的。类似于jquery对象的链式,可是它有自己的方法。在创建之后,你能够用不论什么以下涉及到的方法,不管是直接链式调用。还是保存这个对象到变量。并在这个变量上调用一个或多个方法。

    • deferred.always()
        加入操作方法,无论延迟对象是处于解决状态还是拒绝状态都被调用。


    • deferred.done()
       加入操作方法,仅仅有延迟对象处于已解决状态才被调用
    • deferred.fail()
       加入操作方法,仅仅有延迟对象处于被拒绝状态才会被调用
    • deferred.isRejected()
        推断一个延迟对象是否处于被拒绝状态
    • deferred.isResolved()
        推断一个延迟对象是否处于已解决状态。


    • deferred.notify()
        调用一个给定变量的延迟对象上的进行中的回调。
    • deferred.notifyWith()
        调用一个给定变量和上下文的延迟对象上的进行中的回调。
    • deferred.pipe()
        用来过滤and或or链式延迟的效用方法
    • deferred.progress()
        当延迟对象生成进行中通知时,加入操作被调用。


    • deferred.promise()
        返回延迟允诺对象。


    • deferred.reject()
        拒绝一个延迟对象而且调用不论什么给定參数的失败回调。
    • deferred.rejectWith()
        拒绝回调对象,调用不论什么给定上下文和參数的失败回调。
    • deferred.resolve()
        解决一个延迟对象,而且调用不论什么给定參数的完毕回调。
    • deferred.resolveWith()
        解决一个延迟对象,而且调用不论什么给定上下文和參数的完毕回调。


    • deferred.state()
        推断当前延迟对象状态。
    • deferred.then()
       当延迟对象被解决、拒绝或进行中加入方法被调用。
    • jQuery.Deferred()
        延迟对象的构造函数。


    • jQuery.when()
        提供一个方法运行基于一个或多个对象的回调函数。回调函数常常是代表异步事件的延迟对象
    • .promise()
        当全部的绑定到集合、队列或没有的动作被完毕返回一个promise对象。


       二、延迟对象分析与使用:

       不难得出结论。以上API包含了延迟对象的构建、延迟状态设定方法、延迟状态监听方法。


    延迟对象的数据结构

        延迟对象包含三种状态:resolved(已解决)、rejected(未解决)、progress(进行中)

    这三种状态能够用延迟对象state方法实时查看。


    延迟对象状态查看

       延迟对象是jquery的回调函数解决方式。延迟顾名思义就是延迟到未来某个点再运行,类似jquery 动画函数中delay方法,差别在于后者是延迟固定时间。延迟对象则是通过固定状态推断延迟运行的时机。

    var dtd = $.Deferred(); // 新建一个deferred对象
      var wait = function(dtd){
        var tasks = function(){
          alert("运行完成!

    ");       dtd.resolve(); // 改变deferred对象的运行状态     };     setTimeout(tasks,5000);     return dtd;   }; $.when(wait(dtd))   .done(function(){ alert("哈哈。成功了!

    "); })   .fail(function(){ alert("出错啦!"); });


       上述代码运行流程图:



       
    上述代码样例,延迟对象定义为一个全局对象,这样就会造成延迟状态。能够在不论什么时间进行更改。

       改进的方法一:

    var dtd = $.Deferred(); // 新建一个Deferred对象
      var wait = function(dtd){
        var tasks = function(){
          alert("运行完成!");
          dtd.resolve(); // 改变Deferred对象的运行状态
        };
    
        setTimeout(tasks,5000);
        return dtd.promise(); // 返回promise对象,promise对象仅仅开放与状态无关的方法,即那三种状态方法不开放,无法设置
      };
      var d = wait(dtd); // 新建一个d对象。改为对这个对象进行操作
      $.when(d)
      .done(function(){ alert("哈哈,成功了!

    "); })   .fail(function(){ alert("出错啦!

    "); });   d.resolve(); // 此时。这个语句是无效的


         上述代码,在wait函数返回值是一个promise对象。由下图promise对象数据结构不难发现,promise对象拥有除了改动状态方法以外延迟对象的全部方法,也就是说,promise对象无法改变运行状态,这样就行防止外界对状态的更改。
    promise对象的数据结构


       改进方法二:

       将延迟对象构建成函数内部的局部变量。这样更好的实现了封装,防止外部对状态进行改变。

    var wait = function(dtd){
        var dtd = $.Deferred(); //在函数内部。新建一个Deferred对象
        var tasks = function(){
          alert("运行完成!");
          dtd.resolve(); // 改变Deferred对象的运行状态
        };
    
        setTimeout(tasks,5000);
        return dtd.promise(); // 返回promise对象
      };
      $.when(wait())
      .done(function(){ alert("哈哈,成功了!

    "); })   .fail(function(){ alert("出错啦!

    "); });


           改进方法三:

      直接将函数名作为$.Deferred()參数传入,$.Deferred()所生成的延迟对象会作为wait函数參数传入函数。

    var wait = function(dtd){
        var tasks = function(){
          alert("运行完成。");
          dtd.resolve(); // 改变Deferred对象的运行状态
        };
        setTimeout(tasks,5000);
        return dtd.promise(); // 返回promise对象
      };
     $.Deferred(wait)
      .done(function(){ alert("哈哈,成功了!"); })
      .fail(function(){ alert("出错啦!"); });

    $.Deferred()方式运行状态


       三、项目使用情况:

       乐帝在内推项目中使用的是另外一种方法,即将延迟对象作为局部变量定义。并返回promise对象。这里promise对象与延迟对象除了不能改变状态。对延迟状态的记录及监听方法都同样。

     function loadInternalHost() {
                var dtd = $.Deferred();
                   dtd.resolve();
                return dtd.promise();//在原defferred对象上返回还有一个deferred对象,两个对象都会记录最初deferred对象状态,但后者不能改变状态。其它方法一致
            }



    promise对延迟状态的记录

        当分别调用两个接口时,延迟监听函数同意为多个事件指定一个回调。

        例如以下代码,分别取得内推城市及内推公告两部分数据后,运行兴许载入数据的动作。

    $.when(getInternalRecommendCitys(), getComment()).done(function () {
                    getInternalRecommendJobAdList(oldSearchData.keyWord, oldSearchData.locId);
                });
    function getInternalRecommendCitys() {
                var dtd = $.Deferred();
                $.ajax({
                    type: "get",
                    data: {
                        "openId": openId
                    },
                    dataType: "json",
                    url: "../api/InternalInfo/InternalRecommendCitys",
                    success: function (data) {
                        $city = $("#citySelect");
                        for (var i = 1; i < data.length; i++) {
                            $str = $("<option></option>");
                            $str.text(data[i].name);
                            $str.val(data[i].value);
                            $city.append($str);
                            dtd.resolve();
                        }//将可选城市导入到选择列表
                    },
                    error: function () {
                        dtd.resolve();
                    }
                });
                return dtd.promise();
            }
            function getComment() {
                var dtd = $.Deferred();
                $.ajax({
                    type: "get",
                    data: {
                        "openId": openId
                    },
                    dataType: "json",
                    url: "../api/InternalInfo/GetComment",
                    success: function (data) {
                        $(".notice-content pre").html(data.data);
                        dtd.resolve();
                    },
                    error: function () {
                        dtd.resolve();
                    }
                });//获取数据公布
                return dtd.promise();
            }


  • 相关阅读:
    【软件构造】第二章第一节 软件生命周期和版本控制(配置管理)
    【软件构造】第三章第三节 抽象数据型(ADT)
    【软件构造】第三章第二节 设计规约
    用python实现两个文本合并
    用python实现哈希表
    想要搭建项目 首选从概念理解(一)
    javascript调用rest地址,获取页面值
    ArcGIS Runtime SDK for Mac OS X使用示例
    ArcGIS Server网络分析模块问题汇总
    (ArcGIS Flex API)根据地图数据构建动态树
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4590828.html
Copyright © 2020-2023  润新知