Jquery高级应用Deferred对象原理及使用实例


Posted in jQuery onMay 28, 2020

在实际开发中常常遇到这样的问题:B函数中需要用到的变量或者参数,只有等A函数执行完毕了才能获取到。比如A函数中有一个ajax请求,而B函数中所需要的position变量需要在A函数中ajax请求完成才能得到它的准确值。

function A() {
  $.ajax({
    url: '/api/test',
    type: 'POST',
    data: {...},
    success: function(res) {
      position = res.position;
    }
  })
}

function B() {
  $('.test').text(position);
}

JavaScript的异步模式让B函数不会等待A函数计算出了position的值才会执行,它会不等待A函数的结果而直接开始执行,这样就会造成position无法正确赋值。为了解决这个问题,我们很容易想到使用回调函数,这也是最常用的方法之一

function A(callback) {
  $.ajax({
    url: '/api/test',
    type: 'POST',
    data: {...},
    success: function(res) {
      position = res.position;
      callback && callback();
    }
  })
}

function B() {
  $('.test').text(position);
}

A函数有了回调之后,就可以将B函数当做回调函数传递给A

A(B);

可是如果这个时候,还有一个C函数,依赖于B的执行结果呢,后面甚至有可能出现一个D函数,依赖于C的结果!又如我们常用的ajax,成功了会有一个回调函数,失败了还有一个回调函数,面对这样复杂的情况,我们应该怎么样处理?虽然使用回调函数依然能够搞定这些烦人的难题,但是很显然这并不是一个好的解决办法。

jquery中的Deferred对象很好的解决了这个问题。在了解Deferred之前,我们可能需要了解一个JavaScript中的promise模式。当我们使用回调来解决实际中的问题时,很容易不知不觉中出现代码金字塔

step1(function() {
  step2(function() {
    step3(function() {
      step4(function() {
        step5();
      })
    })
  })
})

假如这个时候有一个js库实现了promise模式,那么我们的代码就会变得清晰可读,并且每一步都会等待上一步执行完毕了才会执行。

new Promise().when(promiseStep1)
.then(promiseStep2)
.then(promiseStep3)
.then(promiseStep4)
.then(promiseStep5);

每一个promise对象都可以设置三种状态:

  • pending [进行中]
  • resolve [已经正确执行]
  • reject [执行失败]

关于promise,还有更多需要了解的地方,我这里只是抛砖引玉。回到jQuery的Deferred对象来。jquery的Deferred对象就是对promise模式的一个很好的实现案例。我们通过一个简单的例子来看看Deferred对象应该如何使用。

函数first是一个耗时两秒的操作,而函数second是一个简单的函数,但是他需要在first执行完毕之后才执行。

function first() {
  setTimeout(function() {
    console.log('first');
  }, 2000);
}
function second() {
  console.log('second');
}
为了达到second在first之后执行,使用Deferred对first函数做一个简单的处理即可
function first() {
  // 1
  var defer = $.Deferred();
  setTimeout(function() {
    console.log('first');
    // 2
    defer.resolve();
  }, 2000);
  
  // 3
  return defer.promise();
}

1、在函数中声明一个Deferred对象,这样在外部就无法修改函数内部的执行状态

2、函数执行完毕,设置执行状态,如果成功执行,defer.resolve(),如果执行失败,则设置为defer.reject()

3、在函数的最后,必须将deferred对象返回出去,否则外部无法得到函数的执行结果

在做了这样的处理之后,我们就可以满足要求的正常使用了

$.when(first())
.done(second());

jquery中,ajax方法就是使用promise模式完成的,我们可以看看常规写法和Deferred对象写法的不同。

// 常规写法
 $.ajax({
   url: '/api/test',
   type: 'POST',
   data: {...},
   success: function(res) {
     // dosomething
   },
   fail: function(res) {
     // dosomething
   },
   complete: function() {
     // dosomething
   }
 })

// 新的写法
$.ajax({
   url: '/api/test',
   type: 'POST',
   ...
 })
 .done(function(res) {
   // success and do something
 })
 .fail(function(res) {
   // fail and do something
 })
 .always(function() {})

这个知识点差不多就总结完毕了。Promise模式与Deferred对象都还有更多值得了解知识点与用法,这是一个非常值得掌握的神兵利器,建议大家搜索更多的文章来学习它。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

jQuery 相关文章推荐
jQuery插件FusionCharts绘制2D环饼图效果示例【附demo源码】
Apr 10 jQuery
jQuery扇形定时器插件pietimer使用方法详解
Jul 18 jQuery
利用JQuery操作iframe父页面、子页面的元素和方法汇总
Sep 10 jQuery
jQuery实现的淡入淡出与滑入滑出效果示例
Apr 18 jQuery
jQuery 导航自动跟随滚动的实现代码
May 30 jQuery
通过jquery的ajax请求本地的json文件方法
Aug 08 jQuery
jQuery表单元素过滤选择器用法实例分析
Feb 20 jQuery
JQuery样式操作、click事件以及索引值-选项卡应用示例
May 14 jQuery
jQuery实现鼠标移入显示蒙版效果
Jan 11 jQuery
jQuery HTML获取内容和属性操作实例分析
May 20 jQuery
jQuery--遍历操作实例小结【后代、同胞及过滤】
May 22 jQuery
jQuery实现倒计时功能完整示例
Jun 01 jQuery
JQuery插件tablesorter表格排序实现过程解析
May 28 #jQuery
jQuery实现鼠标滑动切换图片
May 27 #jQuery
jQuery弹框插件使用方法详解
May 26 #jQuery
jQuery实现的分页插件完整示例
May 26 #jQuery
jQuery 选择器用法实例分析【prev + next】
May 22 #jQuery
jQuery--遍历操作实例小结【后代、同胞及过滤】
May 22 #jQuery
jquery更改元素属性attr()方法操作示例
May 22 #jQuery
You might like
php实现利用phpexcel导出数据
2013/08/24 PHP
ThinkPHP中pathinfo的访问模式、路径访问模式及URL重写总结
2014/08/23 PHP
php+ajax实现无刷新分页的方法
2014/11/04 PHP
php静态文件返回304技巧分享
2015/01/06 PHP
PHP让网站移动访问更加友好方法
2019/02/14 PHP
thinkphp5.1框架中容器(Container)和门面(Facade)的实现方法分析
2019/08/05 PHP
php加速缓存器opcache,apc,xcache,eAccelerator原理与配置方法实例分析
2020/03/02 PHP
用Javscript实现表单复选框的全选功能
2007/05/25 Javascript
关于JavaScript的一些看法
2009/05/27 Javascript
JavaScript实现QueryString获取GET参数的方法
2013/07/02 Javascript
js控制页面的全屏展示和退出全屏显示的方法
2015/03/10 Javascript
javascript跨域原因以及解决方案分享
2015/04/08 Javascript
全面解析Bootstrap表单使用方法(表单控件)
2015/11/24 Javascript
javascript中加var和不加var的区别 你真的懂吗
2016/01/06 Javascript
JS+Canvas 实现下雨下雪效果
2016/05/18 Javascript
JavaScript动态添加事件之事件委托
2016/07/12 Javascript
详解Vue学习笔记进阶篇之列表过渡及其他
2017/07/17 Javascript
详解AngularJS1.x学习directive 中‘& ’‘=’ ‘@’符号的区别使用
2017/08/23 Javascript
使用Vue动态生成form表单的实例代码
2018/04/26 Javascript
微信小程序form表单组件示例代码
2018/07/15 Javascript
[01:02:30]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第三场 8.22
2019/09/05 DOTA
Python实现简单的用户交互方法详解
2018/09/25 Python
PyCharm的设置方法和第一个Python程序的建立
2019/01/16 Python
Django上线部署之IIS的配置方法
2019/08/22 Python
python多线程semaphore实现线程数控制的示例
2020/08/10 Python
施华洛世奇加拿大官网:SWAROVSKI加拿大
2018/06/03 全球购物
银行实习生的自我评价
2013/12/09 职场文书
服务之星事迹材料
2014/05/03 职场文书
招股说明书范本
2014/05/06 职场文书
环境整治工作方案
2014/05/18 职场文书
不遵守课堂纪律的检讨书
2014/09/24 职场文书
2015年个人实习工作总结
2014/12/12 职场文书
出生证明格式
2015/06/15 职场文书
严以律己学习心得体会
2016/01/13 职场文书
PyQt5 QThread倒计时功能的实现代码
2021/04/02 Python
前端传参数进行Mybatis调用mysql存储过程执行返回值详解
2022/08/14 MySQL