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,Angular实现登录界面验证码详解
Apr 27 jQuery
bootstrap+jQuery实现的动态进度条功能示例
May 25 jQuery
jQuery表单设置值的方法
Jun 30 jQuery
jQuery查找和过滤_动力节点节点Java学院整理
Jul 04 jQuery
jQuery实现注册会员时密码强度提示信息功能示例
Sep 05 jQuery
jQuery实现table中两列CheckBox只能选中一个的示例
Sep 22 jQuery
jquery中ajax请求后台数据成功后既不执行success也不执行error的完美解决方法
Dec 24 jQuery
详解使用jQuery.i18n.properties实现js国际化
May 04 jQuery
详解JavaScript原生封装ajax请求和Jquery中的ajax请求
Feb 14 jQuery
JQuery使用属性addClass、removeClass和toggleClass实现增加和删除类操作示例
Nov 18 jQuery
使用jquery实现轮播图效果
Jan 02 jQuery
jQuery class属性操作addClass()与removeClass()、hasClass()、toggleClass()
Mar 31 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
vBulletin Forum 2.3.xx SQL Injection
2006/10/09 PHP
zf框架的校验器InArray使用示例
2014/03/13 PHP
使用php方法curl抓取AJAX异步内容思路分析及代码分享
2014/08/25 PHP
PHP使用递归生成文章树
2015/04/21 PHP
阿里云Win2016安装Apache和PHP环境图文教程
2018/03/11 PHP
Mootools 1.2教程 Fx.Tween的使用
2009/09/15 Javascript
用js实现的模拟jquery的animate自定义动画(2.5K)
2010/07/20 Javascript
整理的比较全的event对像在ie与firefox浏览器中的区别
2013/11/25 Javascript
js/jquery获取文本框输入焦点的方法
2014/03/04 Javascript
JavaScript自定义数组排序方法
2015/02/12 Javascript
js实现发送验证码后的倒计时功能
2015/05/28 Javascript
JavaScript中setUTCFullYear()方法的使用简介
2015/06/12 Javascript
理解javascript定时器中的setTimeout与setInterval
2016/02/23 Javascript
js验证真实姓名与身份证号,手机号的简单实例
2016/07/18 Javascript
浅谈angularjs中响应回车事件
2017/04/24 Javascript
Node.js 8 中的重要新特性
2017/06/28 Javascript
angular项目中bootstrap-datetimepicker时间插件的使用示例
2018/03/15 Javascript
详解javascript replace高级用法
2019/02/17 Javascript
Python 文件管理实例详解
2015/11/10 Python
pycharm安装和首次使用教程
2018/08/27 Python
详解Python 切片语法
2019/06/10 Python
Python button选取本地图片并显示的实例
2019/06/13 Python
详解如何用TensorFlow训练和识别/分类自定义图片
2019/08/05 Python
python中enumerate() 与zip()函数的使用比较实例分析
2019/09/03 Python
python模块常用用法实例详解
2019/10/17 Python
在OpenCV里使用特征匹配和单映射变换的代码详解
2019/10/23 Python
Keras预训练的ImageNet模型实现分类操作
2020/07/07 Python
印度尼西亚最好的小工具在线商店:Erafone.com
2019/03/26 全球购物
诺思信科技(南京)有限公司.NET笔试题答案
2013/07/06 面试题
应届生自荐信范文
2014/02/21 职场文书
社会实践评语
2014/04/28 职场文书
小城镇建设汇报材料
2014/08/16 职场文书
2015年消防工作总结
2015/04/24 职场文书
工作态度恶劣检讨书
2015/05/06 职场文书
(开源)微信小程序+mqtt,esp8266温湿度读取
2021/04/02 Javascript
阿里云服务器部署mongodb的详细过程
2021/09/04 MongoDB