js进阶-promise全方位解析和异步编程
本质:一个构造函数(类),通过实例化。核心机制resolve(标记成功)和reject(标记失败)。Promise 内部通过状态机管理异步操作的结果,外部通过监听状态变更。setTimeout(() => resolve('异步操作成功'), 1000);// 1秒后标记成功});语法糖:基于 Promise 的语法糖,让异步代码看起来像同步代码。本质async函数返回 Pro
Promise 是 JavaScript 异步编程的核心解决方案,也是前端工程师进阶必备的核心知识点。本文将全方位介绍 Promise,涵盖从基础概念到高级应用,再到面试实战的全链路知识。
一、Promises/A+ 规范基础
1. Promise 的状态
Promise 是一个状态机,有且仅有三种状态:
- pending(等待中):初始状态,既不是成功也不是失败。
- fulfilled(已成功):操作成功完成,通过
resolve()
触发。 - rejected(已失败):操作失败,通过
reject()
触发。
🎯 状态不可逆:一旦从 pending 变为 fulfilled 或 rejected,状态将永久固定,不可再次改变。
2. then 方法:核心机制
then
是 Promise 的核心方法,用于注册状态变更后的回调函数:
- 接收两个回调:
- 第一个参数:
onFulfilled
(状态变为 fulfilled 时执行)。 - 第二个参数:
onRejected
(状态变为 rejected 时执行,可选)。
- 第一个参数:
- 回调返回值
-
若回调返回普通值(非 Promise),则新 Promise 以该值 fulfilled。
- 若回调抛出异常,则新 Promise 以该异常 rejected。
- 若回调返回另一个 Promise,则当前 Promise 会跟随该返回 Promise 的状态(链式调用的核心)。
-
const p = new Promise((resolve) => resolve(10));
p.then(
(value) => {
console.log(value); // 10(onFulfilled 回调)
return value * 2; // 返回普通值 → 新 Promise 以 20 fulfilled
},
(err) => console.error(err) // 不会执行(原 Promise 未失败)
).then((newValue) => {
console.log(newValue); // 20(跟随返回的隐式 Promise)
});
3. Promise 解析过程(核心机制)
当 then
的回调返回一个 新的 Promise(记作 P) 时,当前 Promise 会暂停自身的状态变更,转而监听 P 的状态:
- 若 P 变为 fulfilled,则当前 Promise 以 P 的结果 fulfilled;
- 若 P 变为 rejected,则当前 Promise 以 P 的错误 rejected。
🎯 链式调用的本质:通过解析过程实现多个异步操作的依次执行(前一个操作的结果作为下一个操作的输入)。
二、传统异步任务处理的痛点
1. 回调函数模式
早期 JavaScript 通过嵌套回调处理异步(例如 AJAX 请求):
getData(function(result1) {
processResult1(result1, function(result2) {
saveResult2(result2, function(result3) {
// 嵌套层级加深 → 代码难以维护
});
});
});
2. 回调地狱(Callback Hell)
多层嵌套回调会导致代码横向扩展(缩进层级过深),出现“金字塔”结构的代码,可读性差、错误处理困难、难以复用逻辑。
🎯 Promise 的诞生:为了解决回调地狱问题,提供更扁平化的异步代码组织方式。
三、Promise 详解
1. 什么是 Promise?
- 本质:一个构造函数(类),通过
new Promise(executor)
实例化。 - 核心机制:
- executor 是一个同步执行的回调函数,接收两个参数:
resolve
(标记成功)和reject
(标记失败)。 - Promise 内部通过状态机管理异步操作的结果,外部通过
then/catch/finally
监听状态变更。
- executor 是一个同步执行的回调函数,接收两个参数:
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('异步操作成功'), 1000); // 1秒后标记成功
});
2. resolve 的参数规则
resolve
可接受多种类型的参数,处理逻辑不同:
参数类型 |
行为 |
---|---|
普通值(如字符串、数字) |
当前 Promise 以该值 fulfilled。 |
另一个 Promise |
当前 Promise 会跟随该 Promise 的状态(链式调用的基础)。 |
Thenable 对象(含 then 方法的对象) |
会尝试调用其 then 方法,将其转换为标准 Promise 行为。 |
// 示例 1:普通值
Promise.resolve(42).then(v => console.log(v)); // 42
// 示例 2:返回另一个 Promise
Promise.resolve(Promise.resolve('嵌套 Promise')).then(v => console.log(v)); // 嵌套 Promise
// 示例 3:Thenable 对象
const thenable = { then(resolve) { resolve('Thenable 转换成功'); } };
Promise.resolve(thenable).then(v => console.log(v)); // Thenable 转换成功
3. Promise 的实例方法
(1) then 方法
- 参数:
onFulfilled
(成功回调,可选)、onRejected
(失败回调,可选)。 - 返回值:一个新的 Promise(支持链式调用)。
- 回调返回值:决定新 Promise 的状态(如返回普通值、Promise 或抛出异常)。
Promise.resolve(1)
.then(val => val + 1) // 返回普通值 2 → 新 Promise 以 2 fulfilled
.then(val => console.log(val)); // 2
(2) 多次调用 then
- 每次调用
then
都会注册新的回调,按注册顺序依次执行(即使前一个回调异步延迟)。 - 多个
then
可以分别处理同一 Promise 的成功状态。
const p = Promise.resolve(10);
p.then(v => console.log(v)); // 10
p.then(v => console.log(v + 5)); // 15
(3) catch 方法
- 作用:专门捕获 Promise 链中的错误(相当于
then(null, onRejected)
)。 - 参数:错误处理回调(接收错误对象)。
- 特性:可捕获当前 Promise 或链中上游未处理的 rejected 状态。
Promise.reject(new Error('操作失败'))
.catch(err => console.error('捕获错误:', err.message)); // 捕获错误: 操作失败
(4) finally 方法
- 作用:无论 Promise 成功或失败,都会执行的清理逻辑(如关闭加载动画)。
- 参数:无参数回调(无法获取 Promise 的结果或错误)。
- 特性:不会改变原 Promise 的状态或结果。
Promise.resolve('成功')
.finally(() => console.log('无论如何都会执行')) // 无论如何都会执行
.then(v => console.log(v)); // 成功
4. Promise 的类方法
(1) Promise.resolve / Promise.reject
- 作用:快速创建已 resolved/rejected 的 Promise。
- 参数:与
resolve/reject
方法一致。
Promise.resolve('直接成功').then(v => console.log(v)); // 直接成功
Promise.reject('直接失败').catch(e => console.error(e)); // 直接失败
(2) Promise.all
- 作用:并行执行多个 Promise,全部成功时返回结果数组,任一失败立即 rejected。
- 参数:Promise 数组。
- 适用场景:同时发起多个独立异步请求,需全部完成后再处理结果。
Promise.all([
Promise.resolve(1),
Promise.resolve(2),
]).then(([res1, res2]) => console.log(res1, res2)); // 1 2
Promise.all([
Promise.resolve(1),
Promise.reject('失败'),
]).catch(e => console.error(e)); // 失败
(3) Promise.allSettled
- 作用:并行执行多个 Promise,等待所有完成(无论成功/失败),返回每个 Promise 的状态和结果。
- 参数:Promise 数组。
- 适用场景:需要知道所有异步操作的最终状态(如批量提交后统计成功/失败数量)。
Promise.allSettled([
Promise.resolve(1),
Promise.reject('失败'),
]).then(results => {
results.forEach(r => console.log(r.status, r.value || r.reason));
// fulfilled 1
// rejected 失败
});
(4) Promise.race
- 作用:并行执行多个 Promise,返回第一个 settled(成功/失败)的 Promise 结果。
- 参数:Promise 数组。
- 适用场景:超时控制(如请求超时后取消操作)。
Promise.race([
Promise.resolve('快的'),
new Promise(resolve => setTimeout(() => resolve('慢的'), 1000)),
]).then(v => console.log(v)); // 快的
(5) Promise.any
- 作用:并行执行多个 Promise,返回第一个成功的 Promise 结果,全部失败时抛出 AggregateError。
- 参数:Promise 数组。
- 适用场景:多备用数据源(如主接口失败后尝试备用接口)。
Promise.any([
Promise.reject('失败1'),
Promise.resolve('成功'),
]).then(v => console.log(v)); // 成功
四、手写 Promise 实现(核心逻辑)
手写 Promise 是深入理解其原理的最佳方式,需实现以下核心方法(可通过 Jest 编写单元测试验证):
- 构造函数(constructor):接收 executor,管理状态和结果。
- then/catch/finally:注册回调并处理链式调用。
- 类方法(resolve/reject/all/allSettled/race/any):静态工具方法。
🎯 关键点:状态不可逆、then 的链式调用(返回新 Promise)、异步执行回调(通过微任务队列,如
queueMicrotask
)。
下面是一个完整的手写 Promise 实现(支持 Promises/A+ 规范),包含核心方法(constructor
、then
、catch
、finally
)及静态方法(resolve
、reject
、all
、allSettled
、race
、any
),并附带对应的 Jest 单元测试代码。
1.Promise 实现 (myPromise.js)
// 定义 Promise 的三种状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
this.state = PENDING; // 初始状态为 pending
this.value = undefined; // 成功时的值
this.reason = undefined; // 失败时的原因
this.onFulfilledCallbacks = []; // 成功的回调队列
this.onRejectedCallbacks = []; // 失败的回调队列
// 定义 resolve 函数
const resolve = (value) => {
// 只有 pending 状态可以改变
if (this.state === PENDING) {
this.state = FULFILLED;
this.value = value;
// 执行所有成功的回调
this.onFulfilledCallbacks.forEach(fn => fn());
}
};
// 定义 reject 函数
const reject = (reason) => {
// 只有 pending 状态可以改变
if (this.state === PENDING) {
this.state = REJECTED;
this.reason = reason;
// 执行所有失败的回调
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
// 立即执行 executor
executor(resolve, reject);
} catch (error) {
// 如果 executor 执行出错,直接 reject
reject(error);
}
}
// then 方法
then(onFulfilled, onRejected) {
// 处理 then 的参数不是函数的情况
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };
// 返回一个新的 Promise 以实现链式调用
const promise2 = new MyPromise((resolve, reject) => {
// 如果状态是 fulfilled
if (this.state === FULFILLED) {
// 使用 setTimeout 模拟微任务
setTimeout(() => {
try {
const x = onFulfilled(this.value);
// 解析 promise2 和 x 的关系
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else if (this.state === REJECTED) {
// 如果状态是 rejected
setTimeout(() => {
try {
const x = onRejected(this.reason);
// 解析 promise2 和 x 的关系
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else if (this.state === PENDING) {
// 如果状态是 pending,将回调函数存入队列
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
}
// 解析 promise 和 x 的关系
resolvePromise(promise2, x, resolve, reject) {
// 如果 promise2 和 x 是同一个对象,抛出 TypeError
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
// 如果 x 是一个 Promise
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
// 如果 x 是一个普通值
resolve(x);
}
}
// catch 方法
catch(onRejected) {
return this.then(null, onRejected);
}
// finally 方法
finally(callback) {
return this.then(
value => MyPromise.resolve(callback()).then(() => value),
reason => MyPromise.resolve(callback()).then(() => { throw reason; })
);
}
// 静态 resolve 方法
static resolve(value) {
// 如果 value 是一个 Promise,直接返回
if (value instanceof MyPromise) {
return value;
}
// 否则返回一个新的 resolved Promise
return new MyPromise(resolve => resolve(value));
}
// 静态 reject 方法
static reject(reason) {
return new MyPromise((_, reject) => reject(reason));
}
// 静态 all 方法
static all(promises) {
return new MyPromise((resolve, reject) => {
const results = [];
let completed = 0;
const promiseCount = promises.length;
if (promiseCount === 0) {
resolve(results);
return;
}
promises.forEach((promise, index) => {
MyPromise.resolve(promise).then(
value => {
results[index] = value;
completed++;
if (completed === promiseCount) {
resolve(results);
}
},
reason => {
reject(reason);
}
);
});
});
}
// 静态 allSettled 方法
static allSettled(promises) {
return new MyPromise((resolve) => {
const results = [];
let completed = 0;
const promiseCount = promises.length;
if (promiseCount === 0) {
resolve(results);
return;
}
promises.forEach((promise, index) => {
MyPromise.resolve(promise).then(
value => {
results[index] = { status: FULFILLED, value };
completed++;
if (completed === promiseCount) {
resolve(results);
}
},
reason => {
results[index] = { status: REJECTED, reason };
completed++;
if (completed === promiseCount) {
resolve(results);
}
}
);
});
});
}
// 静态 race 方法
static race(promises) {
return new MyPromise((resolve, reject) => {
promises.forEach(promise => {
MyPromise.resolve(promise).then(resolve, reject);
});
});
}
// 静态 any 方法
static any(promises) {
return new MyPromise((resolve, reject) => {
const errors = [];
let rejectedCount = 0;
const promiseCount = promises.length;
if (promiseCount === 0) {
reject(new AggregateError(errors, 'All promises were rejected'));
return;
}
promises.forEach((promise, index) => {
MyPromise.resolve(promise).then(
value => {
resolve(value);
},
reason => {
errors[index] = reason;
rejectedCount++;
if (rejectedCount === promiseCount) {
reject(new AggregateError(errors, 'All promises were rejected'));
}
}
);
});
});
}
}
module.exports = MyPromise;
2.Jest 单元测试 (myPromise.test.js)
const MyPromise = require('./myPromise');
describe('MyPromise', () => {
// 测试构造函数和基本功能
describe('Constructor', () => {
test('should execute executor immediately', () => {
let executed = false;
new MyPromise(() => {
executed = true;
});
expect(executed).toBe(true);
});
test('should handle resolve in executor', (done) => {
new MyPromise((resolve) => {
resolve('success');
}).then((value) => {
expect(value).toBe('success');
done();
});
});
test('should handle reject in executor', (done) => {
new MyPromise((_, reject) => {
reject('error');
}).catch((reason) => {
expect(reason).toBe('error');
done();
});
});
test('should catch executor errors', (done) => {
new MyPromise(() => {
throw new Error('executor error');
}).catch((error) => {
expect(error.message).toBe('executor error');
done();
});
});
});
// 测试 then 方法
describe('then', () => {
test('should handle fulfilled promise', (done) => {
new MyPromise((resolve) => {
resolve('fulfilled');
}).then((value) => {
expect(value).toBe('fulfilled');
done();
});
});
test('should handle rejected promise', (done) => {
new MyPromise((_, reject) => {
reject('rejected');
}).then(null, (reason) => {
expect(reason).toBe('rejected');
done();
});
});
test('should chain then calls', (done) => {
new MyPromise((resolve) => {
resolve(1);
})
.then((value) => {
expect(value).toBe(1);
return value + 1;
})
.then((value) => {
expect(value).toBe(2);
return value + 1;
})
.then((value) => {
expect(value).toBe(3);
done();
});
});
test('should handle async then callbacks', (done) => {
let first = false;
new MyPromise((resolve) => {
resolve(1);
})
.then((value) => {
first = true;
return value + 1;
})
.then((value) => {
expect(first).toBe(true);
expect(value).toBe(2);
done();
});
});
test('should use default onFulfilled if not a function', (done) => {
new MyPromise((resolve) => {
resolve(1);
}).then(null).then((value) => {
expect(value).toBe(1);
done();
});
});
test('should use default onRejected if not a function', (done) => {
new MyPromise((_, reject) => {
reject(1);
}).then(null, null).catch((reason) => {
expect(reason).toBe(1);
done();
});
});
});
// 测试 catch 方法
describe('catch', () => {
test('should catch rejected promise', (done) => {
new MyPromise((_, reject) => {
reject('error');
}).catch((reason) => {
expect(reason).toBe('error');
done();
});
});
test('should chain catch calls', (done) => {
new MyPromise((_, reject) => {
reject('first error');
})
.catch((reason) => {
expect(reason).toBe('first error');
return 'recovered';
})
.then((value) => {
expect(value).toBe('recovered');
done();
});
});
});
// 测试 finally 方法
describe('finally', () => {
test('should execute finally callback', (done) => {
let called = false;
new MyPromise((resolve) => {
resolve('value');
})
.finally(() => {
called = true;
})
.then((value) => {
expect(called).toBe(true);
expect(value).toBe('value');
done();
});
});
test('should pass through value', (done) => {
new MyPromise((resolve) => {
resolve('value');
})
.finally(() => {})
.then((value) => {
expect(value).toBe('value');
done();
});
});
test('should pass through reason', (done) => {
new MyPromise((_, reject) => {
reject('reason');
})
.finally(() => {})
.catch((reason) => {
expect(reason).toBe('reason');
done();
});
});
test('should handle finally callback with return value', (done) => {
new MyPromise((resolve) => {
resolve(1);
})
.finally(() => {
return 2;
})
.then((value) => {
expect(value).toBe(1);
done();
});
});
test('should handle finally callback with promise', (done) => {
new MyPromise((resolve) => {
resolve(1);
})
.finally(() => {
return new MyPromise((resolve) => {
resolve(2);
});
})
.then((value) => {
expect(value).toBe(1);
done();
});
});
});
// 测试静态方法 resolve
describe('static resolve', () => {
test('should resolve with a value', (done) => {
MyPromise.resolve('value').then((value) => {
expect(value).toBe('value');
done();
});
});
test('should resolve with a promise', (done) => {
const p = new MyPromise((resolve) => {
resolve('promise value');
});
MyPromise.resolve(p).then((value) => {
expect(value).toBe('promise value');
done();
});
});
});
// 测试静态方法 reject
describe('static reject', () => {
test('should reject with a reason', (done) => {
MyPromise.reject('reason').catch((reason) => {
expect(reason).toBe('reason');
done();
});
});
});
// 测试静态方法 all
describe('static all', () => {
test('should resolve with an array of values', (done) => {
const p1 = MyPromise.resolve(1);
const p2 = MyPromise.resolve(2);
const p3 = MyPromise.resolve(3);
MyPromise.all([p1, p2, p3]).then((values) => {
expect(values).toEqual([1, 2, 3]);
done();
});
});
test('should reject if any promise rejects', (done) => {
const p1 = MyPromise.resolve(1);
const p2 = MyPromise.reject('error');
const p3 = MyPromise.resolve(3);
MyPromise.all([p1, p2, p3]).catch((reason) => {
expect(reason).toBe('error');
done();
});
});
test('should resolve with empty array', (done) => {
MyPromise.all([]).then((values) => {
expect(values).toEqual([]);
done();
});
});
});
// 测试静态方法 allSettled
describe('static allSettled', () => {
test('should resolve with all settled results', (done) => {
const p1 = MyPromise.resolve(1);
const p2 = MyPromise.reject('error');
const p3 = MyPromise.resolve(3);
MyPromise.allSettled([p1, p2, p3]).then((results) => {
expect(results).toEqual([
{ status: 'fulfilled', value: 1 },
{ status: 'rejected', reason: 'error' },
{ status: 'fulfilled', value: 3 }
]);
done();
});
});
test('should resolve with empty array', (done) => {
MyPromise.allSettled([]).then((results) => {
expect(results).toEqual([]);
done();
});
});
});
// 测试静态方法 race
describe('static race', () => {
test('should resolve with the first resolved promise', (done) => {
const p1 = new MyPromise((resolve) => {
setTimeout(() => resolve(1), 100);
});
const p2 = MyPromise.resolve(2);
MyPromise.race([p1, p2]).then((value) => {
expect(value).toBe(2);
done();
});
});
test('should reject with the first rejected promise', (done) => {
const p1 = new MyPromise((_, reject) => {
setTimeout(() => reject('error'), 100);
});
const p2 = MyPromise.reject('quick error');
MyPromise.race([p1, p2]).catch((reason) => {
expect(reason).toBe('quick error');
done();
});
});
});
// 测试静态方法 any
describe('static any', () => {
test('should resolve with the first resolved promise', (done) => {
const p1 = new MyPromise((resolve) => {
setTimeout(() => resolve(1), 100);
});
const p2 = MyPromise.resolve(2);
MyPromise.any([p1, p2]).then((value) => {
expect(value).toBe(2);
done();
});
});
test('should reject with all rejected promises if all are rejected', (done) => {
const p1 = MyPromise.reject('error1');
const p2 = MyPromise.reject('error2');
MyPromise.any([p1, p2]).catch((error) => {
expect(error.errors).toEqual(['error1', 'error2']);
expect(error.message).toBe('All promises were rejected');
done();
});
});
test('should reject with AggregateError if all are rejected', (done) => {
const p1 = MyPromise.reject('error1');
const p2 = MyPromise.reject('error2');
MyPromise.any([p1, p2]).catch((error) => {
expect(error instanceof Error).toBe(true);
expect(error.message).toBe('All promises were rejected');
// 注意:这里简化了 AggregateError 的实现,实际可能需要更复杂的检查
done();
});
});
});
});
使用说明
- 将 Promise 实现代码保存为
myPromise.js
- 将测试代码保存为
myPromise.test.js
- 确保已安装 Jest (
npm install --save-dev jest
) - 在 package.json 中添加测试脚本:
"scripts": {
"test": "jest"
}
5. 运行测试:npm test
实现说明
这个 Promise 实现包含了以下特性:
- 基本功能:
- 三种状态:pending、fulfilled、rejected
- 构造函数接收 executor 函数
- 异步执行回调(使用 setTimeout 模拟微任务)
- 实例方法:
then()
: 支持链式调用,处理成功和失败情况catch()
: 捕获错误finally()
: 无论成功失败都会执行
- 静态方法:
resolve()
: 创建一个已解决的 Promisereject()
: 创建一个已拒绝的 Promiseall()
: 所有 Promise 都成功时返回结果数组allSettled()
: 所有 Promise 都完成后返回结果状态数组race()
: 返回第一个完成的 Promise 结果any()
: 返回第一个成功的 Promise,或所有都失败时抛出错误
五、async/await 介绍
1. 特点
- 语法糖:基于 Promise 的语法糖,让异步代码看起来像同步代码。
- 本质:
async
函数返回 Promise,await
用于暂停执行直到 Promise 完成。
2. 用法
async function fetchData() {
try {
const result = await Promise.resolve('异步数据'); // 等待 Promise 完成
console.log(result); // 异步数据
} catch (err) {
console.error(err);
}
}
fetchData();
3. 适用场景
- 需要按顺序执行多个异步操作(如先请求用户信息,再请求订单详情)。
- 替代复杂的 Promise 链(提升代码可读性)。
4. 与 Promise 对比
特性 |
async/await |
Promise |
---|---|---|
代码风格 |
类似同步代码,更直观 |
链式调用,需嵌套 then/catch |
错误处理 |
使用 try/catch |
使用 catch 方法 |
可读性 |
高(逻辑线性) |
较低(嵌套层级深时) |
底层原理 |
基于 Promise |
JavaScript 原生异步解决方案 |
六、Promise 相关面试题目
1. 经典面试题:Promise 与事件循环
题目:分析以下代码的输出顺序(结合宏任务与微任务):
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
解题思路:
- 同步代码优先执行:输出
1
→4
。 - 微任务(Promise.then):在当前宏任务结束后立即执行,输出
3
。 - 宏任务(setTimeout):在下一个事件循环中执行,输出
2
。
最终输出顺序:1 → 4 → 3 → 2
。
2. 事件循环(宏任务与微任务)
- 宏任务:script 整体代码、setTimeout、setInterval、I/O 操作。
- 微任务:Promise.then/catch/finally、MutationObserver、queueMicrotask。
执行规则:
- 执行一个宏任务(如 script 代码);
- 执行该宏任务产生的所有微任务;
- 渲染页面(如有必要);
- 执行下一个宏任务。
3. 解题思路总结
- Promise 状态机:明确 pending → fulfilled/rejected 的不可逆性。
- then 的链式调用:每次 then 返回新 Promise,回调返回值决定新状态。
- 事件循环优先级:微任务 > 宏任务(理解这一规则可解决 80% 的异步面试题)。
通过本文的全方位解析,你已掌握 Promise 的核心原理、实战用法及面试要点。结合实际项目中的异步场景(如 API 请求、文件读取),灵活运用 Promise 和 async/await,可显著提升代码质量和开发效率! 🚀
更多推荐
所有评论(0)