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实现多张图片上传预览(不经过后端处理)
Apr 29 jQuery
jQuery动画_动力节点节点Java学院整理
Jul 04 jQuery
jQuery事件_动力节点Java学院整理
Jul 05 jQuery
Mui使用jquery并且使用点击跳转新窗口的实例
Aug 19 jQuery
jQuery实现所有验证通过方可提交的表单验证
Nov 21 jQuery
jquery写出PC端轮播图实例
Jan 26 jQuery
在vue项目中使用Jquery-contextmenu插件的步骤讲解
Jan 27 jQuery
jquery实现掷骰子小游戏
Oct 24 jQuery
jQuery实现form表单基于ajax无刷新提交方法实例代码
Nov 04 jQuery
jQuery插件simplePagination的使用方法示例
Apr 28 jQuery
jQuery实现的分页插件完整示例
May 26 jQuery
jQuery实现推拉门效果
Oct 19 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 开发环境配置(测试开发环境)
2010/04/28 PHP
调试PHP程序的多种方法介绍
2014/11/06 PHP
PHP中浮点数计算比较及取整不准确的解决方法
2015/01/09 PHP
使用PHPExcel操作Excel用法实例分析
2015/03/26 PHP
PHP计算数组中值的和与乘积的方法(array_sum与array_product函数)
2016/04/01 PHP
功能强大的php文件上传类
2016/08/29 PHP
JavaScript 不只是脚本
2007/05/30 Javascript
解决AJAX中跨域访问出现'没有权限'的错误
2008/08/20 Javascript
jQuery之自动完成组件的深入解析
2013/06/19 Javascript
7个JS基础知识总结
2014/03/05 Javascript
jquery的attr方法禁用表单元素禁用输入内容
2014/06/23 Javascript
jQuery实现简单的日期输入格式化控件
2015/03/12 Javascript
js 获取元素在页面上的偏移量的方法汇总
2015/04/13 Javascript
详解js静态检查工具eslint配置文件
2018/11/23 Javascript
Vue.js组件高级特性实例详解
2018/12/24 Javascript
vue-i18n结合Element-ui的配置方法
2019/05/20 Javascript
Vue中实现回车键切换焦点的方法
2020/02/19 Javascript
python自动化工具日志查询分析脚本代码实现
2013/11/26 Python
Python中让MySQL查询结果返回字典类型的方法
2014/08/22 Python
python类和继承用法实例
2015/07/07 Python
不管你的Python报什么错,用这个模块就能正常运行
2018/09/14 Python
详解Python odoo中嵌入html简单的分页功能
2019/05/29 Python
pytorch 加载(.pth)格式的模型实例
2019/08/20 Python
Anaconda使用IDLE的实现示例
2020/09/23 Python
HTML5 Canvas的性能提高技巧经验分享
2013/07/02 HTML / CSS
英国网上购买门:Direct Doors
2018/06/07 全球购物
美国家居装饰店:Pier 1
2019/09/04 全球购物
俄罗斯园林植物网上商店:Garshinka
2020/07/16 全球购物
创业计划书模版
2014/02/05 职场文书
毕业生班级鉴定评语
2015/01/04 职场文书
感谢信范文大全
2015/01/23 职场文书
检讨书范文1000字
2015/01/28 职场文书
颐和园导游词400字
2015/01/30 职场文书
教师专业技术工作总结2015
2015/05/13 职场文书
推广普通话主题班会
2015/08/17 职场文书
JavaScript中document.activeELement焦点元素介绍
2021/11/27 Javascript