热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

前端编程提高之旅(九)----延迟对象

近日做内部推荐项目,在进入项目首页时,需要进行预调用接口判断,按照以往的习惯,应该将调用接口后执行的代码,放入ajax请求success内执行。这样当然可以,但是代码组织和可读性都没有那么高。通过查看Jquery官网api发现了deferredobject(延迟对象)这个概念。  一、API文档

            近日做内部推荐项目,在进入项目首页时,需要进行预调用接口判断,按照以往的习惯,应该将调用接口后执行的代码,放入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 ");
                        $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();
        }



推荐阅读
  • 本文将详细介绍如何在ThinkPHP6框架中实现多数据库的部署,包括读写分离的策略,以及如何通过负载均衡和MySQL同步技术优化数据库性能。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 在PHP后端开发中遇到一个难题:通过第三方类文件发送短信功能返回的JSON字符串无法解析。本文将探讨可能的原因并提供解决方案。 ... [详细]
  • 本文详细介绍了如何使用 HTML 和 CSS 对文件上传按钮进行样式美化,使用户界面更加友好和美观。 ... [详细]
  • 当unique验证运到图片上传时
    2019独角兽企业重金招聘Python工程师标准model:public$imageFile;publicfunctionrules(){return[[[na ... [详细]
  • 一个登陆界面
    预览截图html部分123456789101112用户登入1314邮箱名称邮箱为空15密码密码为空16登 ... [详细]
  • 本文探讨了2019年前端技术的发展趋势,包括工具化、配置化和泛前端化等方面,并提供了详细的学习路线和职业规划建议。 ... [详细]
  • 本文深入探讨了JavaScript中实现继承的四种常见方法,包括原型链继承、构造函数继承、组合继承和寄生组合继承。对于正在学习或从事Web前端开发的技术人员来说,理解这些继承模式对于提高代码质量和维护性至关重要。 ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • 本文介绍了如何利用JavaScript或jQuery来判断网页中的文本框是否处于焦点状态,以及如何检测鼠标是否悬停在指定的HTML元素上。 ... [详细]
  • 深入理解Vue.js:从入门到精通
    本文详细介绍了Vue.js的基础知识、安装方法、核心概念及实战案例,帮助开发者全面掌握这一流行的前端框架。 ... [详细]
  • 本文详细介绍了如何在Kendo UI for jQuery的数据管理组件中,将行标题字段呈现为锚点(即可点击链接),帮助开发人员更高效地实现这一功能。通过具体的代码示例和解释,即使是新手也能轻松掌握。 ... [详细]
  • 使用JS、HTML5和C3创建自定义弹出窗口
    本文介绍如何结合JavaScript、HTML5和C3.js来实现一个功能丰富的自定义弹出窗口。通过具体的代码示例,详细讲解了实现过程中的关键步骤和技术要点。 ... [详细]
  • Spring Boot 中静态资源映射详解
    本文深入探讨了 Spring Boot 如何简化 Web 应用中的静态资源管理,包括默认的静态资源映射规则、WebJars 的使用以及静态首页的处理方法。通过本文,您将了解如何高效地管理和引用静态资源。 ... [详细]
  • 本文提供了多种方法来计算给定年份和月份的起始日和结束日,并进一步探讨了如何根据年、月、周获取特定周的起始日和结束日。 ... [详细]
author-avatar
缅甸环球国际
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有