以jQuery中$.Deferred对象为例讲解promise对象是如何处理异步问题


Posted in Javascript onNovember 13, 2015

Promises是一种令代码异步行为更加优雅的抽象,它很有可能是JavaScript的下一个编程范式,一个Promise即表示任务结果,无论该任务是否完成。

在一些现代浏览器中已经提供了原生的Promise对象,其遵循Promise/A+标准。在jQuery1.5+,提供了$.Deferred(其可以被转化为promise对象)。很多知名的框架中,也提供了promise对象。promise对象在javascript中已经是一种很重要的模式,它在解决异步问题时表现出的优雅,正是javascript所需要的。以下以jQuery中的$.Deferred对象为例,来看一下promise对象是如何处理异步问题。关于$.Deferred对象,可以到jQuery官网查看,这里就不赘述了。

一、封装异步操作

首先,我们以加载图片为例,看以下代码:

//加载图片函数
var loadImg = function(url){
var img = new Image() , deferred = $.Deferred() ;
 img.src = url ;
 img.onload = function(){
  //成功则触发deferred.resolve


deferred.resolve( this ) ;
 } ;
 img.onerror = function(e){

  //失败则触发deferred.reject
  deferred.reject( e );
 } ;

//返回promise对象
 return deferred.promise() ;
} ;
//请求图片
var request = loadImg('http://r2.ykimg.com/0515000054AFFC2D6737B343930AFAD6') ;
//请求成功
request.done(function(img){

//code
}) ;
//可以注册多个回调,当请求成功时,会按注册的顺序执行,fail和always也有此性质
request.done(function(img){

// code
});
//请求失败
request.fail(function(){

// code
}) ;
//请求完毕
request.always(function(){

//code
});

以上的代码,我封装了图片加载的操作,将他们委托给$.Deferred,最后生成一个promise返回。使用这样的方式,相比用对外暴露回调的方式,显得更干净、更清晰。这么做的另一个更重要的原因是,promise的连接。

二、promise的连接

我们还是以上面图片加载的代码为例,来看一下如何做promise的连接,看以下代码:

var request = loadImg('http://b1.hucdn.com/upload/item/1411/13/89613257775992_800x800.jpg') ;
request.done(function(img){
//code
}) ;
//request连接别的promise之后返回的promise
var request3 = request.then(function(img){

//request执行成功时 连接request1

var request1 = loadImg('http://b1.hucdn.com/upload/item/1410/19/29492535741725_800x800.jpg') ;

return request1 ;
},function(e){

//request执行失败时 连接request2

var request2 = loadImg('http://b1.hucdn.com/upload/item/1410/19/29492535741725_800x800.jpg') ;

return request2 ;
});
//request执行并且request1或request2成功执行时
request3.done(function(done){

//code
}) ;

 promise对象提供了then的方法,它接受两个回调:onResolve和onReject,在回调中返回promise,就可以完成promise之间的连接。通过这种方式,可以使异步操作串行的执行。

同时,jQuery还提供了另外一种连接方式,看代码:

var request = loadImg('http://b1.hucdn.com/upload/item/1412/23/48188827139381_800x800.jpg') ;
var request1 = loadImg('http://b1.hucdn.com/upload/item/1412/06/50258594673502_800x800.jpg') ;
//通过$.when连接promise
var request2 = $.when(request,request1) ;
request2.done(function(img,img){
//code
}) ;

jQuery中提供了$.when这个函数,它可以接受n个promise对象为参数,它是将promise的执行结果连接在一起。使用这种方式,多个异步操作可以并行执行。

三、The End

这里的代码是以加载图片为例,同样的做法可以应用到其他的异步操作中去。比如jQuery中的$.ajax、$.fn.animate,调用它们返回的就是promise。在node端,也可以把一些异步操作(读数据库、读文件等)封装成promise。继而对多个promise实现合并的操作,使其串行或者并行执行。

附:deferred对象

deferred除了用于转化promise对象外,本身也是个很有用的对象。它除了提供像promise对象的那些方法和属性外,还有notify函数和progress函数,这两个函数在实现进度条和瀑布流的时候,有很大的用处。

   在实现进度条时,resolve和done函数可以用于定义进度条读取到100%时的触发时机和触发逻辑,notify和progress函数可以用于定义进度条在读取中的触发时机和触发逻辑。reject和fail函数可以用于定义进度读取失败时的触发时机和触发逻辑。

   在实现瀑布流时,resolve和done函数可以用于定义当数据已经全部加载到页面的触发时机和触发逻辑,notify和progress函数可以用于定义瀑布流读取下一页的触发时机和触发逻辑。

Javascript 相关文章推荐
表单提交验证类
Jul 14 Javascript
JavaScript的目的分析
Jan 05 Javascript
Packer 3.0 JS压缩及混淆工具 下载
May 03 Javascript
浅析JavaScript 箭头函数 generator Date JSON
May 23 Javascript
Cookies 和 Session的详解及区别
Apr 21 Javascript
用JavaScript做简易的购物车的代码示例
Oct 20 Javascript
初学者AngularJS的环境搭建过程
Oct 27 Javascript
JS实现对json对象排序并删除id相同项功能示例
Apr 18 Javascript
新手必须知的Node.js 4个JavaScript基本概念
Sep 16 Javascript
纯js实现无缝滚动功能代码实例
Feb 21 Javascript
从零开始在vue-cli4配置自适应vw布局的实现
Jun 08 Javascript
TypeScript 运行时类型检查补充工具
Sep 28 Javascript
Jquery promise实现一张一张加载图片
Nov 13 #Javascript
jquery转盘抽奖功能实现
Nov 13 #Javascript
javascript生成随机数方法汇总
Nov 12 #Javascript
js正则表达式验证邮件地址
Nov 12 #Javascript
每天一篇javascript学习小结(Boolean对象)
Nov 12 #Javascript
为何JS操作的href都是javascript:void(0);呢
Nov 12 #Javascript
基于jquery实现左右按钮点击的图片切换效果
Jan 27 #Javascript
You might like
PHP 中的批处理的实现
2007/06/14 PHP
PHP删除特定数组内容并且重建数组索引的方法.
2011/03/25 PHP
Laravel实现autoload方法详解
2017/05/07 PHP
js实现仿QQ秀换装效果的方法
2015/03/04 Javascript
jQuery获取file控件中图片的宽高与大小
2016/08/04 Javascript
js实现从左向右滑动式轮播图效果
2017/07/07 Javascript
js通过Date对象实现倒计时动画效果
2017/10/27 Javascript
vue2.0 根据状态值进行样式的改变展示方法
2018/03/13 Javascript
jQuery实现获取动态添加的标签对象示例
2018/06/28 jQuery
JS逻辑运算符短路操作实例分析
2018/07/09 Javascript
解决bootstrap模态框数据缓存的问题方法
2018/08/10 Javascript
JavaScript实现表单注册、表单验证、运算符功能
2018/10/15 Javascript
Javascript 实现 Excel 导入生成图表功能
2018/10/22 Javascript
uploadify插件实现多个图片上传并预览
2019/09/30 Javascript
JS正则表达式验证端口范围(0-65535)
2020/01/06 Javascript
Javascript如何递归遍历本地文件夹
2020/08/06 Javascript
JavaScript实现简易计算器小功能
2020/10/22 Javascript
[02:45]DOTA2英雄基础教程 伐木机
2013/12/23 DOTA
以一段代码为实例快速入门Python2.7
2015/03/31 Python
Python实现字典按照value进行排序的方法分析
2017/12/23 Python
python实现键盘控制鼠标移动
2020/11/27 Python
Python Image模块基本图像处理操作小结
2019/04/13 Python
python实现共轭梯度法
2019/07/03 Python
python3.x+pyqt5实现主窗口状态栏里(嵌入)显示进度条功能
2019/07/04 Python
Python定时任务APScheduler的实例实例详解
2019/07/22 Python
python中通过selenium简单操作及元素定位知识点总结
2019/09/10 Python
Python利用命名空间解析XML文档
2020/08/10 Python
简单英文演讲稿
2014/01/01 职场文书
对祖国的寄语大全
2014/04/11 职场文书
2014年光棍节活动策划方案(创意集锦)
2014/09/29 职场文书
银行贷款委托书范本
2014/10/11 职场文书
工作批评与自我批评范文
2014/10/16 职场文书
2016新年慰问信范文
2015/03/25 职场文书
于丹讲座视频观后感
2015/06/15 职场文书
2016年端午节寄语
2015/12/04 职场文书
高中体育课教学反思
2016/02/16 职场文书