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 相关文章推荐
符合W3C网页标准的iframe标签的使用方法
Jul 19 Javascript
javascript脚本编程解决考试分数统计问题
Oct 18 Javascript
IE iframe的onload方法分析小结
Jan 07 Javascript
jquery+json 通用三级联动下拉列表
Apr 19 Javascript
把字符串按照特定的字母顺序进行排序的js代码
Jan 28 Javascript
jQuery获取和设置表单元素的方法
Feb 14 Javascript
Javascript类型转换的规则实例解析
Feb 23 Javascript
jQuery仿京东商城楼梯式导航定位菜单
Jul 25 Javascript
jQuery Mobile和HTML5开发App推广注册页
Nov 07 Javascript
超级简易的JS计算器实例讲解(实现加减乘除)
Aug 08 Javascript
新手vue构建单页面应用实例代码
Sep 18 Javascript
JS中的函数与对象的创建方式
May 12 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 ajax 分页类代码
2008/11/13 PHP
php array_push()数组函数:将一个或多个单元压入数组的末尾(入栈)
2011/07/12 PHP
PHP判断表单复选框选中状态完整例子
2014/06/24 PHP
php5.4传引用时报错问题分析
2016/01/22 PHP
php简单实现数组分页的方法
2016/04/30 PHP
浅谈PHP各环境下的伪静态配置
2019/03/13 PHP
PHP解密支付宝小程序的加密数据、手机号的示例代码
2021/02/26 PHP
列表内容的选择
2006/06/30 Javascript
Jquery中val()表单取值赋值的实例代码
2013/08/15 Javascript
jQuery实现复选框全选/取消全选/反选及获得选择的值
2014/06/12 Javascript
Windows系统下使用Sublime搭建nodejs环境
2015/04/13 NodeJs
很棒的一组js图片轮播特效
2017/01/12 Javascript
微信小程序开发之选项卡(窗口底部TabBar)页面切换
2017/04/12 Javascript
bootstrap select2插件用ajax来获取和显示数据的实例
2018/08/09 Javascript
[06:16]《DAC最前线》之地区预选赛全面回顾
2015/01/19 DOTA
使用python编写脚本获取手机当前应用apk的信息
2014/07/21 Python
玩转python爬虫之cookie使用方法
2016/02/17 Python
python 获取网页编码方式实现代码
2017/03/11 Python
对Python+opencv将图片生成视频的实例详解
2019/01/08 Python
djang常用查询SQL语句的使用代码
2019/02/15 Python
Python 获取ftp服务器文件时间的方法
2019/07/02 Python
python随机模块random的22种函数(小结)
2020/05/15 Python
canvas简单连线动画的实现代码
2020/02/04 HTML / CSS
Big Green Smile德国网上商店:提供各种天然产品
2018/05/23 全球购物
美国社交购物市场:MassGenie
2019/02/18 全球购物
美国葡萄酒网上商店:Martha Stewart Wine Co.
2019/03/17 全球购物
清扬洗发水广告词
2014/03/14 职场文书
中专毕业生的自荐书
2014/07/01 职场文书
运动会铅球比赛加油稿
2014/09/26 职场文书
2014年林业工作总结
2014/12/05 职场文书
文明家庭事迹材料
2014/12/20 职场文书
《亲亲我的妈妈》观后感(3篇)
2019/09/26 职场文书
python基于tkinter制作无损音乐下载工具
2021/03/29 Python
详解RedisTemplate下Redis分布式锁引发的系列问题
2021/04/27 Redis
简单聊一聊SQL注入及防止SQL注入
2022/03/23 MySQL
nginx 添加http_stub_status_module模块
2022/05/25 Servers