promise通过状态机解决异步回调地狱,其核心为三种不可逆状态与then链式调用,借助微任务实现异步执行,并通过resolvePromise处理返回值,支持链式传递与错误捕获。

Promise 是 javaScript 中处理异步操作的核心机制之一。它解决了传统回调函数带来的“回调地狱”问题,让异步代码更清晰、可读性更强。本文将从使用方式入手,逐步深入到 Promise 的基本实现原理,帮助你全面理解其工作机制。
Promise 的基本使用
Promise 表示一个异步操作的最终完成或失败,以及其返回的结果值。它有三种状态:
- pending(进行中):初始状态,既没有完成也没有失败。
- fulfilled(已成功):操作成功完成。
- rejected(已失败):操作失败。
一旦状态从 pending 变为 fulfilled 或 rejected,就不会再改变。
创建一个 Promise 实例:
立即学习“Java免费学习笔记(深入)”;
const myPromise = new Promise((resolve, reject) => { // 异步操作 setTimeout(() => { const success = true; if (success) { resolve('操作成功'); } else { reject('操作失败'); } }, 1000); });
通过 then 方法注册成功和失败的回调:
myPromise .then(value => { console.log(value); // 输出: 操作成功 }) .catch(error => { console.error(error); });
catch 方法用于捕获错误,等价于 then(NULL, rejection)。finally 方法则在 Promise 结束后执行,不论成功或失败,适合做清理工作。
Promise 链式调用与异步流程控制
Promise 支持链式调用,每个 then 返回一个新的 Promise,从而避免嵌套回调。
fetchData() .then(data => process(data)) .then(result => save(result)) .then(() => console.log('保存成功')) .catch(err => console.error('出错:', err));
注意:在 then 中返回普通值会作为下一个 Promise 的输入;返回新的 Promise 时,后续 then 会等待其完成。
常见场景如顺序请求多个接口:
getUser() .then(user => getUserPosts(user.id)) .then(posts => displayPosts(posts)) .catch(showError);
Promise 常用静态方法
es6 提供了几个有用的静态方法来简化异步操作管理:
- Promise.resolve(value):返回一个以给定值解析后的 Promise。
- Promise.reject(reason):返回一个以给定原因为拒因的 Promise。
- Promise.all(iterable):所有 Promise 都成功才成功,任意一个失败则整体失败。
- Promise.race(iterable):返回最先完成(无论成功或失败)的 Promise 结果。
- Promise.allSettled(iterable):等待所有 Promise 完成,返回它们的结果数组(包含 status 和 value/reason)。
- Promise.any(iterable):返回第一个 fulfilled 的 Promise,全部失败才 reject。
例如使用 Promise.all 并行加载资源:
Promise.all([ fetch('/api/user'), fetch('/api/config'), loadScript('/utils.js') ]) .then(results => { console.log('所有资源加载完成'); }) .catch(err => { console.error('至少一个请求失败', err); });
简易 Promise 源码实现
为了理解 Promise 内部机制,我们可以实现一个简化版的 Promise 类。
核心要点:
- 状态不可逆(pending → fulfilled / rejected)
- 支持 then 方法链式调用
- 异步执行回调(使用 queueMicrotask 或 setTimeout 模拟)
- 处理 then 回调的返回值(特别是 Promise)
function MyPromise(executor) { this.state = 'pending'; this.value = undefined; this.reason = undefined; this.onFulfilledCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled'; this.value = value; this.onFulfilledCallbacks.forEach(fn => fn()); } }; const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn()); } }; try { executor(resolve, reject); } catch (err) { reject(err); } } MyPromise.prototype.then = function(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val; onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; }; const promise2 = new MyPromise((resolve, reject) => { if (this.state === 'fulfilled') { queueMicrotask(() => { try { const x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }); } if (this.state === 'rejected') { queueMicrotask(() => { try { const x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }); } if (this.state === 'pending') { this.onFulfilledCallbacks.push(() => { queueMicrotask(() => { try { const x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }); }); this.onRejectedCallbacks.push(() => { queueMicrotask(() => { try { const x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }); }); } }); return promise2; }; function resolvePromise(promise, x, resolve, reject) { if (promise === x) { return reject(new TypeError('Chaining cycle detected')); } let called = false; if (x != null && (typeof x === 'object' || typeof x === 'function')) { try { const then = x.then; if (typeof then === 'function') { then.call(x, y => { if (called) return; called = true; resolvePromise(promise, y, resolve, reject); }, r => { if (called) return; called = true; reject(r); }); } else { resolve(x); } } catch (e) { if (called) return; called = true; reject(e); } } else { resolve(x); } }
这个实现涵盖了 Promise/A+ 规范的核心逻辑,包括:
- 状态管理
- 回调队列存储
- 微任务调度(保证异步执行)
- then 链的返回值处理(尤其是 Promise 穿透)
虽然省略了 finally、catch 等方法,但已足够说明其运行机制。
基本上就这些。理解 Promise 不仅要会用,更要明白它是如何通过状态机和事件循环协作实现异步控制的。掌握源码思路有助于应对复杂异步场景,也为学习 async/await 打下基础。
以上就是javascript中的Promise使用与源码解析_


