Javascript中的异步编程规范Promises/A详细介绍


Posted in Javascript onJune 06, 2014

Javascript里异步编程逐渐被大家接受,先前大家一般通过回调嵌套,setTimeout、setInterval等方式实现,代码看起来非常不直观,不看整个代码逻辑很难快速理解。Javascript里异步函数大概有I/O函数(Ajax、postMessage、img load、script load等)、计时函数(setTimeout、setInterval)等。

这些我们都很熟悉,在复杂的应用中往往会嵌套多层,甚至以为某些步骤未完成而导致程序异常,最简单的例子:比如你往DOM中注入节点,你必须等待节点注入后在操作这个节点,当大量节点注入的时候,时间往往很难把握。如果我们得代码依赖第三方api的数据。我们无法获悉一个API响应的延迟时间,应用程序的其他部分可能会被阻塞,直到它返回结果。Promises对这个问题提供了一个更好的解决方案,它是非阻塞的,并且与代码完全解耦 。

那么,我看看Javascript里异步编程,首先推荐大家看看相对来说比较流行的Promises/A规范。

Promises/A规范

注:为了便于理解,描述可能和Promises/A规范有所出入;

CommonJS之Promises/A规范,通过规范API接口来简化异步编程,使我们的异步逻辑代码更易理解。
遵循Promises/A规范的实现我们称之为Promise对象,Promise对象有且仅有三种状态:unfulfilled(未完成)、fulfilled(已完成)、failed(失败/拒绝);初始创建的时候是unfulfilled(未完成)状态,状态只可以从unfulfilled(未完成)变成fulfilled(已完成),或者unfulfilled(未完成)变成failed(失败/拒绝)。状态一旦变成fulfilled(已完成)或者failed(失败/拒绝),状态就不能再变了。

Promises/A规范提供了一个在程序中描述延时(或将来)概念的解决方案。主要的思想不是执行一个方法然后阻塞应用程序等待结果返回后再回调其他方法,而是返回一个Promise对象来满足未来监听。fulfilled状态和failed状态都可以被监听。Promise通过实现一个then接口来返回Promise对象来注册回调:

then(fulfilledHandler, errorHandler, progressHandler);

then接口用于监听一个Promise的不同状态。fulfilledHandler用于监听fulfilled(已完成)状态,errorHandler用于监听failed(失败/拒绝)状态,progressHandler用于监听unfulfilled(未完成)状态。Promise不强制实现unfulfilled(未完成)的事件监听(例如我们知道旧版本的jQuery(1.5,1.6)的Deferred就是一个Promise的实现,但没有实现对unfulfilled(未完成)状态的监听来回调progressHandler)。

一般认为,then接口返回的是一个新的Promise对象,而不是原来的Promise对象,这个新的新的Promise对象可以理解为是原来Promise对象的一个视图,它只包含原有Promise对象的一组方法,这些方法只能观察原有Promise对象的状态,而无法更改deferred对象的内在状态。这样可以避免多个调用者之间的冲突,多个调用者可以通过改变新的Promise对象状态而不影响别的调用者。

另外,Promise提供了resolve(实现状态由未完成到已完成)和reject(实现状态由未完成到拒绝或失败)两个接口实现状态的转变。

发一张图片帮助理解一下:

Javascript中的异步编程规范Promises/A详细介绍

有了Promise,就可以以同步的思维去编写异步的逻辑了。在异步函数里,不能使用try/catch捕获异常,也不能抛出异常。有了Promise,我们可以直接显式定义errorHandler,相当于捕获异常。

以下是几个遵循Promises/A规范的类库,when,q,rsvp.js,jQuery.Deferred等等。

Javascript 相关文章推荐
javascript 进阶篇2 CSS XML学习
Mar 14 Javascript
通过JS自动隐藏手机浏览器的地址栏实现原理与代码
Jan 02 Javascript
js实现鼠标拖动图片并兼容IE/FF火狐/谷歌等主流浏览器
Jun 06 Javascript
浅析JS刷新框架中的其他页面 && JS刷新窗口方法汇总
Jul 08 Javascript
Js与Jq 获取页面元素值的方法和差异对比
Apr 30 Javascript
浅谈JavaScript中的string拥有方法的原因
Aug 28 Javascript
Bootstrap导航栏各元素操作方法(表单、按钮、文本)
Dec 28 Javascript
基于JavaScript如何实现ajax调用后台定义的方法
Dec 29 Javascript
AngularJS教程之环境设置
Aug 16 Javascript
JavaScript正则替换HTML标签功能示例
Mar 02 Javascript
浅谈Vue.js中如何实现自定义下拉菜单指令
Jan 06 Javascript
vue修改Element的el-table样式的4种方法
Sep 17 Javascript
AMD异步模块定义介绍和Require.js中使用jQuery及jQuery插件的方法
Jun 06 #Javascript
jQuery插件开发详细教程
Jun 06 #Javascript
手写的一个兼容各种浏览器的javascript getStyle函数(获取元素的样式)
Jun 06 #Javascript
jquery进行数组遍历如何跳出当前的each循环
Jun 05 #Javascript
js检验密码强度(低中高)附图
Jun 05 #Javascript
原生js编写设为首页兼容ie、火狐和谷歌
Jun 05 #Javascript
js如何判断用户是否是用微信浏览器
Jun 05 #Javascript
You might like
PHP 简单日历实现代码
2009/10/28 PHP
php 图片加水印与上传图片加水印php类
2010/05/12 PHP
php对二维数组进行相关操作(排序、转换、去空白等)
2015/11/04 PHP
PHP快速推送微信模板消息
2017/04/14 PHP
PHP中常见的密码处理方式和建议总结
2018/10/14 PHP
JS应用之禁止抓屏、复制、打印
2008/02/21 Javascript
js removeChild 障眼法 可能出现的错误
2009/10/06 Javascript
TinyMCE 新增本地图片上传功能
2010/11/05 Javascript
Node.js生成HttpStatusCode辅助类发布到npm
2013/04/09 Javascript
JavaScript字符串对象的concat方法实例(用于连接两个或多个字符串)
2014/10/16 Javascript
jQuery中first()方法用法实例
2015/01/06 Javascript
jquery datatable服务端分页
2016/08/31 Javascript
AngularJS中关于ng-class指令的几种实现方式详解
2016/09/17 Javascript
JavaScript定时器实现的原理分析
2016/12/06 Javascript
用WebStorm进行Angularjs 2开发(环境篇:Windows 10,Angular-cli方式)
2018/12/05 Javascript
JavaScript实现Excel表格效果
2020/02/07 Javascript
vue二选一tab栏切换新做法实现
2021/01/19 Vue.js
[53:21]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS LGD-CDEC
2014/05/22 DOTA
[51:34]Ti4主赛事胜者组 DK vs EG 2
2014/07/19 DOTA
[07:26]2015国际邀请赛第二日TOP10集锦
2015/08/06 DOTA
python Django批量导入数据
2016/03/25 Python
利用Python中unittest实现简单的单元测试实例详解
2017/01/09 Python
Python迭代器与生成器基本用法分析
2018/07/26 Python
使用turtle绘制五角星、分形树
2019/10/06 Python
python多进程(加入进程池)操作常见案例
2019/10/21 Python
python tornado使用流生成图片的例子
2019/11/18 Python
使用python写一个自动浏览文章的脚本实例
2019/12/05 Python
Python imutils 填充图片周边为黑色的实现
2020/01/19 Python
描述JSP和Servlet的区别、共同点、各自应用的范围
2012/10/02 面试题
医学生临床实习自我评价
2014/03/07 职场文书
年度考核登记表个人总结
2015/03/06 职场文书
借条如何写
2015/05/26 职场文书
php TP5框架生成二维码链接
2021/04/01 PHP
python入门学习关于for else的特殊特性讲解
2021/11/20 Python
详解MySQL中timestamp和datetime时区问题导致做DTS遇到的坑
2021/12/06 MySQL
关于Python使用turtle库画任意图的问题
2022/04/01 Python