JavaScript Promise

JavaScript Promise完全指南

JavaScript Promise完全指南

小白也能理解的异步编程核心知识点

什么是Promise?

Promise 就像是你在快餐店点餐时拿到的小票:

  • 当你点餐时,服务员给你一张小票(创建一个Promise)
  • 这张小票代表餐厅对你的承诺(Promise),会在未来某个时刻给你食物
  • 食物可能成功准备好(fulfilled),也可能因为食材用完失败(rejected)
  • 拿到食物后,小票就完成了它的使命(settled)

💡 简单说:Promise是表示异步操作最终完成或失败的对象

// 创建一个Promise
const myPromise = new Promise((resolve, reject) => {
  // 异步操作,比如从服务器获取数据
  // 成功时调用resolve(结果)
  // 失败时调用reject(错误原因)
});

为什么需要Promise?

在Promise出现之前,我们使用回调函数处理异步操作:

回调地狱 😱

getUser(userId, function(user) {
  getPosts(user.id, function(posts) {
    getComments(posts[0].id, function(comments) {
      // 更多嵌套…
    });
  });
});

问题:代码难以阅读和维护(俗称”回调地狱”)

Promise解决方案 ✨

getUser(userId)
  .then(user => getPosts(user.id))
  .then(posts => getComments(posts[0].id))
  .then(comments => {
    // 处理评论
  })
  .catch(error => console.error(error));

优势:链式调用,代码更清晰,错误处理更简单

Promise的三种状态

每个Promise对象都有三种可能的状态:

Pending
(等待中)
Fulfilled
(已成功)
Rejected
(已失败)
  • Pending(待定):初始状态,操作尚未完成
  • Fulfilled(已兑现):操作成功完成
  • Rejected(已拒绝):操作失败

⚠️ 重点:状态一旦改变就不会再变(不可逆)

🌰 实例:

const promise = new Promise((resolve, reject) => {
  // 初始状态是 pending

  // 5秒后状态变为 fulfilled
  setTimeout(() => resolve(“成功啦!”), 5000);

  // 或者如果发生错误:
  // reject(new Error(“出问题啦!”));
});

使用Promise:then/catch/finally

then() – 处理完成状态

当Promise成功时执行

promise.then(
  result => { /* 处理成功结果 */ },
  error => { /* 处理错误(可选) */ }
);

catch() – 处理失败状态

当Promise失败时执行(专门处理错误)

promise.catch(
  error => { /* 处理错误 */ }
);

finally() – 无论成功失败都执行

清理工作(如关闭加载动画)

promise.finally(() => {
  // 无论成功失败都会执行
  // 适合做清理工作
});

💡 最佳实践:使用链式调用

fetchData()
  .then(data => processData(data))
  .then(result => displayResult(result))
  .catch(error => showError(error))
  .finally(() => hideLoader());

Promise链式调用

Promise最强大的功能之一:可以将多个异步操作链接在一起

// 模拟获取用户数据
function getUser(id) {
  return new Promise(resolve => {
    setTimeout(() => resolve({ id, name: ‘小明’ }), 1000);
  });
}

// 模拟获取用户订单
function getOrders(userId) {
  return new Promise(resolve => {
    setTimeout(() => resolve([‘订单1’, ‘订单2’]), 800);
  });
}

// 链式调用
getUser(123)
  .then(user => {
    console.log(‘用户:’, user.name);
    return getOrders(user.id); // 返回新的Promise
  })
  .then(orders => {
    console.log(‘订单:’, orders);
  })
  .catch(error => {
    console.error(‘出错:’, error);
  });

💡 链式调用的关键在于:每个then()方法都返回一个新的Promise

Promise静态方法

Promise.all() – 所有成功才算成功

等待所有Promise完成,如果全部成功则返回结果数组,如果有一个失败则立即失败

Promise.all([
  promise1,
  promise2,
  promise3
])
.then(results => {
  // results = [result1, result2, result3]
})
.catch(error => {
  // 任何一个Promise失败就会到这里
});

Promise.race() – 谁先完成用谁

多个Promise竞赛,哪个先完成(无论成功失败)就用哪个的结果

Promise.race([
  fastPromise,
  slowPromise
])
.then(firstResult => {
  // 使用最先完成的结果
});

Promise.allSettled() – 等所有都完成

等待所有Promise完成(无论成功失败),返回每个Promise的状态和结果

Promise.any() – 只要有1个成功

多个Promise中只要有一个成功就返回结果,全部失败才返回失败

🌰 实例:同时加载多个资源

// 同时加载用户数据和配置数据
Promise.all([
  fetch(‘/api/user’),
  fetch(‘/api/config’)
])
.then(([userData, configData]) => {
  // 两个请求都完成才执行
  initializeApp(userData, configData);
});

常见错误与误区

误区1:忘记返回Promise

// 错误写法
somePromise
  .then(result => {
    anotherAsyncOperation(result); // 忘记return!
  })
  .then(newResult => {
    // newResult是undefined!
  });
// 正确写法
somePromise
  .then(result => {
    return anotherAsyncOperation(result); // 返回Promise
  })
  .then(newResult => {
    // 正常获得结果
  });

误区2:没有捕获错误

// 错误:未处理的Promise拒绝
asyncFunction().then(result => {
  // 如果出错怎么办?
});
// 正确:总是添加catch处理
asyncFunction()
  .then(result => { … })
  .catch(error => console.error(error));

误区3:Promise构造函数中使用try/catch

// 不推荐
new Promise((resolve, reject) => {
  try {
    // 异步操作
  } catch (error) {
    reject(error);
  }
}); // 推荐:异步错误不会在try/catch中捕获
new Promise((resolve, reject) => {
  // 直接处理错误
  asyncOperation(param, (err, result) => {
    if (err) reject(err);
    else resolve(result);
  });
});

Promise总结

Promise是处理JavaScript异步操作的强大工具,它让异步代码更易读、更易维护

关键要点:理解三种状态、掌握链式调用、正确处理错误、善用静态方法

学习建议:多练习,在实际项目中应用Promise,逐渐过渡到async/await

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部