详细介绍 JavaScript 中的 Promises/A 异步编程规范
这篇文章主要介绍了 JavaScript 中的异步编程规范 Promises/A 详细介绍,同时介绍了 jQuery 中的 Deferred 和 Promises,需要的朋友可以参考下。
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(实现状态由未完成到拒绝或失败)两个接口实现状态的转变。
发一张图片帮助理解一下:
有了 Promise,就可以以同步的思维去编写异步的逻辑了。在异步函数里,不能使用 try/catch 捕获异常,也不能抛出异常。有了 Promise,我们可以直接显式定义 errorHandler,相当于捕获异常。
相关类库
以下是几个遵循 Promises/A 规范的类库
- when.js
- q.js
- rsvp.js
- jQuery.Deferred
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论