深入理解 JavaScript 异步编程:Promises/A 规范详解

作者:函数茶馆

时间:2026-10-28

浏览:215

本文详细介绍 JavaScript 中 Promises/A 规范的核心机制,解析 Promise 对象的三种状态(unfulfilled、fulfilled、failed)及其转换规则。重点阐述 then 接口的回调注册逻辑、状态隔离原理以及 resolve/reject 方法的使用,帮助开发者以同步思维编写更清晰的异步代码,并列举了 when、q 等主流实现库。

文章目录

JavaScript 异步编程背景与痛点

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 规范

注:为便于理解,部分描述可能与 Promises/A 规范原文存在细微差异;

CommonJS 的 Promises/A 规范通过标准化 API 接口来简化异步编程,使异步逻辑代码更易于理解。遵循该规范的实现被称为 Promise 对象,它仅有三种状态:unfulfilled(未完成)、fulfilled(已完成)和 failed(失败/拒绝)。初始创建时处于 unfulfilled 状态,状态只能从 unfulfilled 变为 fulfilled 或 failed。一旦状态变为 fulfilled 或 failed,便不可再改变。

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

then 接口与状态监听

代码如下:

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 对象的视图,仅包含原对象的一组方法,用于观察其状态,无法更改 deferred 对象的内部状态。这避免了多个调用者之间的冲突,各调用者可通过改变新 Promise 对象的状态而不影响其他调用者。

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

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

JavaScript 异步编程背景与痛点

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

主流 Promise 实现库

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

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章