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 相关文章推荐
utf-8编码引起js输出中文乱码的解决办法
Jun 23 Javascript
JavaScript ECMA-262-3 深入解析.第三章.this
Sep 28 Javascript
js 火狐下取本地路径实现思路
Apr 02 Javascript
JavaScript运动减速效果实例分析
Aug 04 Javascript
angularjs学习笔记之简单介绍
Sep 26 Javascript
AngularJS实现元素显示和隐藏的几个案例
Dec 09 Javascript
第十章之巨幕页头缩略图与警告框组件
Apr 25 Javascript
深入理解vue-loader如何使用
Jun 06 Javascript
前端开发不得不知的10个最佳ES6特性
Aug 30 Javascript
微信小程序实现tab页面切换功能
Jul 13 Javascript
jQuery 筛选器简单操作示例
Oct 02 jQuery
游戏开发中如何使用CocosCreator进行音效处理
Apr 14 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
Zerg基本策略
2020/03/14 星际争霸
linux下为php添加curl扩展的方法
2011/07/29 PHP
smarty表格换行实例
2014/12/15 PHP
php列出mysql表所有行和列的方法
2015/03/13 PHP
全新Mac配置PHP开发环境教程
2016/02/03 PHP
PHP的Laravel框架中使用消息队列queue及异步队列的方法
2016/03/21 PHP
Zend Framework过滤器Zend_Filter用法详解
2016/12/09 PHP
Yii1.1中通过Sql查询进行的分页操作方法
2017/03/16 PHP
js中有关IE版本检测
2012/01/04 Javascript
js实现广告漂浮效果的小例子
2013/07/02 Javascript
ie中js创建checkbox默认选中问题探讨
2013/10/21 Javascript
原生js获取宽高与jquery获取宽高的方法关系对比
2014/04/04 Javascript
jQuery中on()方法用法实例详解
2015/02/06 Javascript
JS获取子窗口中返回的数据实现方法
2016/05/28 Javascript
[原创]JavaScript语法高亮插件highlight.js用法详解【附highlight.js本站下载】
2016/11/01 Javascript
JavaScript 字符串常用操作小结(非常实用)
2016/11/30 Javascript
React+react-dropzone+node.js实现图片上传的示例代码
2017/08/23 Javascript
利用python批量给云主机配置安全组的方法教程
2017/06/21 Python
django数据库migrate失败的解决方法解析
2018/02/08 Python
在Python中将函数作为另一个函数的参数传入并调用的方法
2019/01/22 Python
使用pandas读取文件的实现
2019/07/31 Python
Python双链表原理与实现方法详解
2020/02/22 Python
如何使用PyCharm将代码上传到GitHub上(图文详解)
2020/04/27 Python
python 实现aes256加密
2020/11/27 Python
TensorFlow低版本代码自动升级为1.0版本
2021/02/20 Python
html5指南-3.如何实现html元素拖拽功能
2013/01/07 HTML / CSS
html5清空画布方法(三种)
2017/10/16 HTML / CSS
英国独特礼物想法和个性化礼物网站:notonthehighstreet.com
2018/04/16 全球购物
法国高保真音响和家庭影院商店:Son Video
2019/04/26 全球购物
室内设计自我鉴定
2013/10/15 职场文书
机电专业毕业生推荐信
2013/11/10 职场文书
同学聚会老师邀请函
2014/01/28 职场文书
公司节能减排方案
2014/05/16 职场文书
农业项目合作意向书
2015/05/08 职场文书
离婚纠纷代理词
2015/05/23 职场文书
十月围城观后感
2015/06/08 职场文书