加载笔记内容...
加载笔记内容...
在异步编程领域,Promise 作为 JavaScript 的核心异步处理机制,其重要性不言而喻。本文将从基础到高级层层递进,结合最新规范和实践经验,深度解析 Promise 的方方面面。
Promise 的核心是一个有限状态机,包含三个基本状态:
resolve
触发reject
触发状态转换的关键特性:
1const stateDiagram = `
2 [*] --> Pending
3 Pending --> Fulfilled : resolve()
4 Pending --> Rejected : reject()
5 Fulfilled --> [*]
6 Rejected --> [*]
7`;
在部分文档中会混用 Resolved 和 Fulfilled 这两个术语。严格来说:
Promise 的回调执行属于微任务(Microtask),与事件循环机制密切相关:
1console.log('Start');
2Promise.resolve().then(() => console.log('Microtask'));
3setTimeout(() => console.log('Macrotask'), 0);
4console.log('End');
5
6// 输出顺序:
7// Start → End → Microtask → Macrotask
执行优先级:
.then()
方法的核心在于创建新的 Promise 并建立处理链:
1class Promise {
2 constructor(executor) {
3 // ...初始化状态和队列
4 this._resolveQueue = [];
5 this._rejectQueue = [];
6 }
7
8 then(onFulfilled, onRejected) {
9 return new Promise((resolve, reject) => {
10 const wrappedFulfilled = value => {
11 try {
12 const result = onFulfilled(value);
13 result instanceof Promise
14 ? result.then(resolve, reject)
15 : resolve(result);
16 } catch (e) {
17 reject(e);
18 }
19 };
20
21 this._resolveQueue.push(wrappedFulfilled);
22 // 类似处理 reject 逻辑
23 });
24 }
25}
链式调用特性:
.then()
返回新 Promise特性 | Promise.all | Promise.allSettled |
---|---|---|
成功条件 | 全部成功 | 全部完成(无论成功失败) |
返回值结构 | 值数组 | 对象数组(含状态字段) |
失败处理 | 立即失败 | 等待所有结果 |
典型应用场景 | 强依赖并行请求 | 批量操作结果收集 |
最佳实践:
1// 安全的数据获取模式
2const results = await Promise.allSettled(requests);
3const successfulData = results
4 .filter(p => p.status === 'fulfilled')
5 .map(p => p.value);
ES2021 新增的 Promise.any
实现了"第一个成功"模式:
1const fastest = await Promise.any([
2 fetch('/api/v1'),
3 fetch('/api/v2'),
4 fetch('/api/v3')
5]);
注意事项:
虽然 Promise 本身不支持取消,但可通过 AbortController 实现:
1const controller = new AbortController();
2
3async function fetchWithCancel(url) {
4 const response = await fetch(url, {
5 signal: controller.signal
6 });
7 // ...处理响应
8}
9
10// 取消请求
11controller.abort();
未处理的 Promise 链可能造成内存泄漏:
1// 错误示例
2function createPromiseChain() {
3 return Promise.resolve()
4 .then(() => { /* 可能长时间挂起的操作 */ });
5}
6
7// 正确做法:添加终止条件
8const abortController = new AbortController();
9function createSafePromise() {
10 return Promise.race([
11 longRunningTask(),
12 new Promise((_, reject) => {
13 abortController.signal.onabort = () =>
14 reject(new DOMException('Aborted', 'AbortError'));
15 })
16 ]);
17}
根据 Promises/A+ 规范,合格实现需满足:
then(null, onRejected)
应传递值测试验证:
1// Promises/A+ 兼容性测试
2const promisesAplusTests = require('promises-aplus-tests');
3const adapter = {
4 resolved: Promise.resolve,
5 rejected: Promise.reject,
6 deferred: () => {
7 const obj = {};
8 obj.promise = new Promise((resolve, reject) => {
9 obj.resolve = resolve;
10 obj.reject = reject;
11 });
12 return obj;
13 }
14};
15
16promisesAplusTests(adapter, function (err) {
17 err && console.error(err);
18});
1// 模块顶层直接使用 await
2const data = await fetchData();
3export default data;
1const { promise, resolve, reject } = Promise.withResolvers();
Promise 作为现代 JavaScript 异步编程的基石,理解其核心机制对开发高质量应用至关重要。在实践中应:
.catch()
或 try/catch
with async/await)通过深入理解 Promise 的底层机制,开发者可以更好地驾驭异步编程,构建更健壮的 JavaScript 应用。