javascript异步编程代码书写规范Promise学习笔记


Posted in Javascript onFebruary 11, 2015

最近工作轻松了点,想起了以前总是看到的一个单词promise,于是耐心下来学习了一下。

一:Promise是什么?为什么会有这个东西?

首先说明,Promise是为了解决javascript异步编程时候代码书写的方式产生的。
随着javascript的发展,异步的场景越来越多。前端有AJAX,setTimeout等,后端Node异步更多。按照传统的做法,那么就是各种回调嵌回调。代码可以把人绕晕。
这个时候,CommonJS社区提出了一个叫做Promise/A+的规范,这个规范定义了如何书写异步代码,包括使用when/then/resolve等来组织异步的代码。
这个规范由于很优雅,所以相继就有很多人实现了这个规范,其中包括 浏览器原生支持的Promise(), jQuery里面的deferred,when.js等。
因为这几个库都符合该规范,所以学习一个也就可以了。我主要学习了jQuery的deferred,所以本文主要讲讲这个实现。
 
二:jQuery的deferred

首先,关于deferred对象,阮一峰老师有篇文章写的很详细了,地址点这。建议可以先看看他的那篇文章,再继续往下看。
上面说过,promise是为了解决异步(比如ajax)的,那么我们来对比下他们的区别。
经典的jQuery的AJAX的写法是

$.ajax({

    type: "get",

    url: "",

    success: function () {},

    error; function () {}

});

其中success和error参数便是成功/失败时候的回调函数。 

而现在jQuery的AJAX写法成了

$.ajax({

    type; "get",

    url: ""

}).done(function () {}).fail(function () {});

其中成功后会调用done里面的函数,失败便会调用fail里面的函数。 

看到这里也许你就会有疑问了,done/fail这些方法是哪个对象上的?$.ajax()返回了什么对象,为什么有这两个方法?
答案就在下面介绍的Deferred对象。

jQuery提供了一种新的类型Deferred。通过$.Deferred()来生成。例如

var def = $.Deferred();

这个def继承了很多方法,有done/fail/resolve/reject等。
所以这里我们也就知道,上面$.ajax()其实返回的也就是这个对象。
 
deferred对象有很多方法,这里介绍几种常用的,更多的可以参考 API
 
首先自然是生成一个def对象。这里有很多方法,比如:

var def = $.Deferred();    // 自己生成

$.ajax({});    // ajax方法返回的也是def对象

$.when();    // when方法也会返回一个def对象

这里,$.when()可以单独讲讲,这个方法通常接收一个或多个deferred对象,然后根据这些deferred对象的状态情况,来决定$.when()返回的对象的状态。其中有个使用场景就是多个ajax请求,如果其中一个失败就都算失败,那么便可以在$.when()中传入多个ajax方法,例如$.when($.ajax(), $.ajax())。然后$.when会返回一个def对象(根据这两个请求结果的来判断)。
 
接着得到了def对象,便有了一系列改变这个对象状态的方法

def.resolve();    // 把def对象设置成已经完成,然后便会立刻执行绑定在def.done()里面的函数。

def.reject();    // 把def对象设置成已经失败,然后便会立刻执行绑定在def.fail()里面的函数。

def.notify();    // def对象执行中,对应的回调是def.progress()。

紧接着是设置回调的方法,顺序和上面的对应,也就是什么状态会调用到什么回调

def.done();    // 对应def.resolve();

def.fail();    // 对应def.reject();

def.progress();    // 对应 def.notify();

// 特殊的

def.always();    // 成功或者失败都会调用

def.then();    // 接受多个函数,按顺序依次是成功(done),失败(fail)和进行中(progress)

其实到这里位置,deferred对象的用法也就差不多了。不过jQuery还提供了几个API

// 检查当前状态类

def.isRejected();

def.isResolved();

def.state();

这几个api顾名思义,就不具体讲了,具体可以查看上面给的jQuery API文档。
 
还有一个方法,就是有时候我们希望给外部一个def对象,然后这个对象可以设置各种状态的回调,但是不能改变它的状态,那么就可以用

def.promise();

返回一个promiese对象,是deferred对象的子集,可以用done/fail等方法,没有resolve/reject等方法,主要是为了保护不让外部去修改def对象的状态。 

至此,关于promise已经全部讲完,大家现在就可以把它用在自己的项目中了,另外提早给大家拜个早年,祝大家羊年洋洋得意^ ^。

Javascript 相关文章推荐
静态图片的十一种滤镜效果--不支持Ie7及非IE浏览器。
Mar 06 Javascript
jQuery实现鼠标划过修改样式的方法
Apr 14 Javascript
JS简单循环遍历json数组的方法
Apr 22 Javascript
js中使用使用原型(prototype)定义方法的好处详解
Jul 04 Javascript
jq stop()和:is(:animated)的用法及区别(详解)
Feb 12 Javascript
jQuery EasyUI window窗口使用实例代码
Dec 25 jQuery
详解Angular5 服务端渲染实战
Jan 04 Javascript
详解vue 单页应用(spa)前端路由实现原理
Apr 04 Javascript
layui原生表单验证的实例
Sep 09 Javascript
JS sort排序详细使用方法示例解析
Sep 27 Javascript
通过实例解析js可枚举属性与不可枚举属性
Dec 02 Javascript
javascript条件式访问属性和箭头函数介绍
Nov 17 Javascript
jquery实现动态操作select选中
Feb 11 #Javascript
JS操作HTML自定义属性的方法
Feb 10 #Javascript
jQuery制作仿Mac Lion OS滚动条效果
Feb 10 #Javascript
jQuery扁平化风格下拉框美化插件FancySelect使用指南
Feb 10 #Javascript
javascript中定义类的方法详解
Feb 10 #Javascript
JavaScript判断浏览器类型的方法
Feb 10 #Javascript
javascript定时器完整实例
Feb 10 #Javascript
You might like
PHP 批量删除 sql语句
2009/06/05 PHP
php中删除数组的第一个元素和最后一个元素的函数
2015/03/07 PHP
Joomla语言翻译类Jtext用法分析
2016/05/05 PHP
php面向对象的用户登录身份验证
2017/06/08 PHP
javascript生成/解析dom的CDATA类型的字段的代码
2007/04/22 Javascript
Document:getElementsByName()使用方法及示例
2013/10/28 Javascript
对之前写的jquery分页做下升级
2014/06/19 Javascript
点击A元素触发B元素的事件在IE8下会识别成A元素
2014/09/04 Javascript
jquery插件NProgress.js制作网页加载进度条
2015/06/05 Javascript
JS实现从网页顶部掉下弹出层效果的方法
2015/08/06 Javascript
JS实现具备延时功能的滑动门菜单效果
2015/09/17 Javascript
jQuery实现倒计时(倒计时年月日可自己输入)
2016/12/02 Javascript
vue父组件通过props如何向子组件传递方法详解
2017/08/16 Javascript
深入理解node.js http模块
2018/01/24 Javascript
详解Webpack多环境代码打包的方法
2018/08/03 Javascript
createObjectURL方法实现本地图片预览
2019/09/30 Javascript
Layui表格监听行单双击事件讲解
2019/11/14 Javascript
通过实例解析chrome如何在mac环境中安装vue-devtools插件
2020/07/10 Javascript
详解element-ui 表单校验 Rules 配置 常用黑科技
2020/07/11 Javascript
[36:09]Secret vs VG 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.24
2019/09/10 DOTA
PyQt5实现QLineEdit添加clicked信号的方法
2019/06/25 Python
详解Python对JSON中的特殊类型进行Encoder
2019/07/15 Python
Django使用消息提示简单的弹出个对话框实例
2019/11/15 Python
Python高级编程之继承问题详解(super与mro)
2019/11/19 Python
Python安装OpenCV的示例代码
2020/03/05 Python
Python加速程序运行的方法
2020/07/29 Python
详解纯CSS3制作的20种loading动效
2017/07/05 HTML / CSS
新秀丽官方旗舰店:Samsonite拉杆箱、双肩包、皮具
2018/03/05 全球购物
劳力士官方珠宝商:J.R. Dunn Jewelers
2018/09/29 全球购物
工商管理专业实习生自我鉴定
2013/09/29 职场文书
护理专业推荐信
2013/11/07 职场文书
2014年3.15团委活动总结
2014/03/16 职场文书
房地产公司见习自我鉴定
2014/04/28 职场文书
工商干部先进事迹
2014/05/14 职场文书
缓存替换策略及应用(以Redis、InnoDB为例)
2021/07/25 Redis
SQL使用复合索引实现数据库查询的优化
2022/05/25 SQL Server