掌握JavaScript异步编程需先理解Promise状态流转与链式调用机制,再运用Async/Await简化语法;二者是封装关系而非替代,Promise是基础,Async/Await是其语法糖。

掌握JavaScript异步编程,核心是理解Promise的运行机制和Async/Await的语法糖本质。它们不是替代关系,而是层层封装:Async/Await建立在Promise之上,让异步代码写起来像同步,但执行逻辑完全依赖Promise的状态流转。
Promise:用链式调用来管理异步流程
Promise是一个表示“未来某个时刻可能完成或失败”的对象。它有三种状态:pending(进行中)、fulfilled(成功)、rejected(失败),且状态不可逆。
关键点在于:
– 构造Promise时,执行器函数立即执行,内部的异步操作(如setTimeout、fetch)才真正延迟;
– .then() 和 .catch() 总是异步执行(属于微任务),即使Promise已处于fulfilled状态;
– 错误会自动向下穿透,未被捕获的reject会一直传到链尾的.catch();
– 多个.then()串联时,前一个.then()的返回值会作为下一个.then()的输入(自动包装成Promise,除非返回的是Promise实例本身)。
常见写法示例:
const p = new Promise(resolve => setTimeout(() => resolve(42), 100)); p.then(x => x * 2).then(console.log); // 84,两步都在微任务队列中执行
Async/Await:让Promise使用更自然
async函数本质是返回Promise的函数;await只能用在async函数内,它会暂停函数执行,等待右侧表达式(必须是Promise或thenable)resolve后,再把结果作为await表达式的值继续执行。
立即学习“Java免费学习笔记(深入)”;
注意细节:
– await 后面不加return,函数仍会返回Promise;
– await 只解包一层Promise,不会递归展开嵌套Promise;
– try/catch捕获的是await抛出的异常,等价于Promise链中的.catch();
– 多个await按顺序执行,想并发应改用Promise.all([p1, p2])。
对比写法:
// Promise链
fetch('/api/user').then(res => res.json()).then(user => console.log(user));
// 等效的async/await
async function getUser() {
const res = await fetch('/api/user');
const user = await res.json();
console.log(user);
}
关键区别:语义、控制力与错误处理习惯
– 错误传播方式不同:Promise链靠.catch()集中捕获或逐级处理;Async/Await靠try/catch块,更接近同步代码思维;
– 调试体验更好:await让调用栈更线性,浏览器断点可逐行停,而Promise链的.then()回调会跳转到新执行上下文;
– 并发控制更直观:Promise.all([...]) 是显式并发;多个独立await是串行,容易误写成阻塞式请求;
– 不能直接在顶层await(ES2022前),需包裹在async IIFE中,而Promise可以随时new。
实际建议:从Promise入手,用Async/Await落地
– 先彻底搞懂Promise的三种状态、链式调用、错误冒泡和Promise.all/race的用途;
– 写业务代码优先用async/await,结构清晰、易读易维护;
– 遇到需要并行请求、竞速、批量处理时,别硬套await,回到Promise方法组合;
– 不要为用await而拆分逻辑,比如把本可一次fetch的数据,拆成多次await请求——这是性能陷阱。











