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 相关文章推荐
js下获取div中的数据的原理分析
Apr 07 Javascript
基于jQuery的计算文本框字数的代码
Jun 06 Javascript
JavaScript通过Date-Mask将日期转换成字符串的方法
Jun 04 Javascript
41个Web开发者必须收藏的JavaScript实用技巧
Jul 22 Javascript
微信小程序-拍照或选择图片并上传文件
Jan 06 Javascript
React Js 微信禁止复制链接分享禁止隐藏右上角菜单功能
May 26 Javascript
Vue.js中数据绑定的语法教程
Jun 02 Javascript
vue-router实现tab标签页(单页面)详解
Oct 17 Javascript
Vue监听数据渲染DOM完以后执行某个函数详解
Sep 11 Javascript
使用Vue 实现滑动验证码功能
Jun 27 Javascript
Vue根据条件添加click事件的方式
Nov 09 Javascript
微信小程序实现日历小功能
Nov 18 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
让Json更懂中文(JSON_UNESCAPED_UNICODE)
2011/10/27 PHP
关于php操作mysql执行数据库查询的一些常用操作汇总
2013/06/24 PHP
PHP通过API获取手机号码归属地
2015/05/28 PHP
CodeIgniter集成smarty的方法详解
2016/05/26 PHP
PHP巧妙利用位运算实现网站权限管理的方法
2017/03/12 PHP
PHP扩展安装方法步骤解析
2020/11/24 PHP
在多个页面使用同一个HTML片段的代码
2011/03/04 Javascript
JavaScript创建类/对象的几种方式概述及实例
2013/05/06 Javascript
JS实现Enter键跳转及控件获得焦点
2013/08/12 Javascript
asm.js使用示例代码
2013/11/28 Javascript
js清空表单数据的两种方式(遍历+reset)
2014/07/18 Javascript
jQuery中live()方法用法实例
2015/01/19 Javascript
javascript中闭包(Closure)详解
2016/01/06 Javascript
jQuery Mobile开发中日期插件Mobiscroll使用说明
2016/03/02 Javascript
Bootstrap表单布局样式源代码
2016/07/04 Javascript
详解React native fetch遇到的坑
2018/08/30 Javascript
通过Nodejs搭建网站简单实现注册登录流程
2019/06/14 NodeJs
js实现盒子移动动画效果
2020/08/09 Javascript
vue路由的配置和页面切换详解
2020/09/09 Javascript
python通过自定义isnumber函数判断字符串是否为数字的方法
2015/04/23 Python
Python Sql数据库增删改查操作简单封装
2016/04/18 Python
快速入手Python字符编码
2016/08/03 Python
Python中生成器和迭代器的区别详解
2018/02/10 Python
django初始化数据库的实例
2018/05/27 Python
浅谈python连续赋值可能引发的错误
2018/11/10 Python
python可视化篇之流式数据监控的实现
2019/08/07 Python
python模块常用用法实例详解
2019/10/17 Python
Django微信小程序后台开发教程的实现
2020/06/03 Python
pytorch实现查看当前学习率
2020/06/24 Python
CSS3实现歌词进度文字颜色填充变化动态效果的思路详解
2020/06/02 HTML / CSS
英智兴达软件测试笔试题
2016/10/12 面试题
办公室副主任岗位职责
2013/11/25 职场文书
党员批评与自我批评材料
2014/10/14 职场文书
2015教师个人师德工作总结
2015/10/23 职场文书
《詹天佑》教学反思
2016/02/20 职场文书
基于PyQT5制作一个桌面摸鱼工具
2022/02/15 Python