

新闻资讯
技术学院Promise 通过链式调用和状态管理将嵌套回调扁平化,其三种状态(pending/fulfilled/rejected)不可逆,.then() 返回新 Promise 实现线性流程,需显式 return 避免链中断。
Promise 是 JavaScript 中用于处理异步操作的对象,它本身不“解决”回调地狱,而是提供了一种可链式调用、可统一错误处理的结构,让嵌套回调变成扁平化流程。
一个 Promise 实例有三种状态:pending(进行中)、fulfilled(成功)、rejected(失败)。状态一旦从 pending 变为 fulfilled 或 rejected,就不可逆。
创建 Promise 时需传入一个执行器函数,它接收两个参数:resolve 和 reject —— 它们是函数,不是关键字:
const p = new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() > 0.5;
if (success) {
resolve('done'); // → fulfilled
} else {
reject(new Error('fail')); // → rejected
}
}, 100);
});
resolve(value) 触发后续 .then() 的第一个回调reject(reason) 触发后续 .catch() 或 .then(null, fn)
throw new Error())会自动被转为 reject
传统回调地狱典型写法:
getData(function(a) {
getMoreData(a, function(b) {
getEvenMore(b, function(c) {
console.log(c);
});
});
});
用 Promise 改写后变成线性流程:
getData() .then(a => getMoreData(a)) .then(b => getEvenMore(b)) .then(c => console.log(c)) .catch(err => console.error(err));
.then() 返回一个
新的 Promise,所以能连续调用.then() 回调返回的是普通值(如字符串、数字),它会被自动包装成 Promise.resolve(value)
reject,都会跳过后续所有 .then(),直接落到最近的 .catch()
这是最常踩的坑:在 .then() 里没显式 return,导致后续 .then() 接收到 undefined,甚至触发静默失败。
错误示例:
fetch('/api/user')
.then(res => res.json())
.then(user => {
fetch(`/api/posts?uid=${user.id}`); // ❌ 忘记 return!
})
.then(posts => console.log(posts)); // 这里拿到的是 undefined
正确写法:
fetch('/api/user')
.then(res => res.json())
.then(user => fetch(`/api/posts?uid=${user.id}`)) // ✅ 显式 return Promise
.then(res => res.json())
.then(posts => console.log(posts));
fetch(...) 是调用,但没 return 就不算返回值)async/await 能天然规避这类问题,但它底层仍依赖 Promise 链行为.then() 开头加 console.log 查看实际传入值真正让 Promise “解耦”回调地狱的,不是语法糖,而是它强制你思考每个异步步骤的产出类型和错误传播路径。链断在哪、为什么断、谁该负责处理错误——这些在嵌套回调里是模糊的,在 Promise 链里是明确可追踪的。