Promise 是需用 new Promise() 构造的对象,执行器函数中必须显式调用 resolve/reject;.then() 链式返回新 Promise,错误需 .catch() 或 try/catch 捕获;async/await 是语法糖但需在 async 函数内使用;Promise 状态不可逆,未处理 rejection 会静默失败。

Promise 基本写法:用 new Promise() 包裹异步操作
Promise 不是语法糖,而是一个对象,必须用 new Promise() 构造,且传入一个执行器函数(executor),它接收 resolve 和 reject 两个参数。常见错误是忘记 return、漏掉 reject、或在同步错误中没调用 reject。
正确示例:
const fetchUser = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() > 0.3;
if (success) {
resolve({ id: 123, name: 'Alice' });
} else {
reject(new Error('Network failed'));
}
}, 500);
});
};
-
resolve和reject必须显式调用,不会自动触发 - 异步操作(如
setTimeout、fetch)必须放在 executor 内部,不能“先执行再包 Promise” - 同步抛错(比如 JSON.parse 错误)不会被 Promise 捕获,需手动
try/catch+reject
.then() 和 .catch() 链式调用:每个 .then() 返回新 Promise
链式调用的关键在于:每个 .then() 的返回值会成为下一个 .then() 的输入;如果返回的是 Promise,则自动等待其完成;如果抛错或返回 Promise.reject(),后续 .then() 会被跳过,直到遇到 .catch()。
避免回调地狱的核心就在这里:把嵌套变成扁平链。
立即学习“Java免费学习笔记(深入)”;
fetchUser()
.then(user => fetchPosts(user.id))
.then(posts => filterActive(posts))
.then(filtered => saveToCache(filtered))
.catch(err => console.error('Failed at:', err.message));
- 不要在
.then()里写if/else分支并混用return和throw—— 容易漏掉错误路径 -
.catch()只捕获前面 Promise 链中的 rejection,不捕获.then()内部的同步异常(除非你手动throw) - 多个并行请求用
Promise.all([p1, p2, p3]),别串行调用三次.then()
async/await 是 Promise 的语法糖:但 await 必须在 async 函数内
很多人写 await fetchUser() 却忘了外层函数加 async,结果报错 Uncaught SyntaxError: await is only valid in async function。
正确写法:
const loadProfile = async () => {
try {
const user = await fetchUser();
const posts = await fetchPosts(user.id);
return { user, posts };
} catch (err) {
console.error('Load failed:', err);
throw err; // 不要静默吞掉错误,下游可能依赖这个 rejection
}
};
-
await后面必须是 Promise(或 thenable),否则直接返回原值 -
try/catch捕获的是 Promise rejection,不是所有 JS 异常(比如undefined.foo()还是同步报错) - 循环中慎用
await:for-of + await 是串行,想并行得用Promise.all(…map(async …))
容易被忽略的坑:Promise 状态不可逆、未处理的 rejection 会静默失败
Promise 一旦 resolve 或 reject,状态就锁定,再次调用另一个方法无效。更危险的是:未被 .catch() 或 try/catch 捕获的 rejection,在现代浏览器和 Node.js 中会触发 unhandledrejection 事件,但默认不报错 —— 你的请求失败了,控制台却没提示。
- 全局监听未处理 rejection(开发期必备):
window.addEventListener('unhandledrejection', e => console.error(e.reason)); - 避免“忘记 return”:箭头函数单表达式隐式 return,但若写成块级结构
() => { doSomething(); }就不返回 Promise,导致链中断 - 构造 Promise 时,
reject最好传Error实例,而不是字符串 —— 方便堆栈追踪和统一错误处理











