promise async await总结
一、Promise 核心概念
-
Promise 是什么?
Promise 是 JavaScript 中用于处理异步操作的对象
,它代表一个尚未完成但预期将来会完成的操作
。 -
Promise 的三种状态
- pending:初始状态,既不是成功也不是失败
- fulfilled:操作成功完成
- rejected:操作失败
-
创建 Promise
const myPromise = new Promise((resolve, reject) => {// 异步操作if (/* 操作成功 */) {resolve('成功的结果');} else {reject('失败的原因');} });
-
Promise 方法链
myPromise.then(result => {console.log(result); // '成功的结果'return '新的值';}).then(newResult => {console.log(newResult); // '新的值'}).catch(error => {console.error(error); // '失败的原因'}).finally(() => {console.log('无论成功失败都会执行');});
二、Promise 高级用法
-
Promise 静态方法
// 所有 Promise 都解决 Promise.all([promise1, promise2]).then(values => console.log(values));// 任意一个 Promise 解决 Promise.race([promise1, promise2]).then(value => console.log(value));// 所有 Promise 都完成(无论成功失败) Promise.allSettled([promise1, promise2]).then(results => console.log(results));// 立即返回一个已解决的 Promise Promise.resolve('立即解决'); Promise.reject('立即拒绝');
-
Promise 链式调用的错误处理
doSomething().then(result => doSomethingElse(result)).then(newResult => doThirdThing(newResult)).catch(error => console.error(error)); // 捕获前面所有 then 中的错误
-
Promise 常见陷阱
// 错误示例:忘记返回 Promise doSomething().then(result => {doSomethingElse(result); // 忘记 return}).then(newResult => {// newResult 会是 undefined});// 正确写法 doSomething().then(result => {return doSomethingElse(result); // 显式返回});
三、async/await 详解
-
async 函数
async function myAsyncFunction() {return 'Hello'; // 自动包装成 Promise }// 等同于 function myAsyncFunction() {return Promise.resolve('Hello'); }
-
await 表达式
async function fetchData() {try {const response = await fetch('api/data'); // 等待 Promise 解决const data = await response.json(); // 再次等待return data;} catch (error) {console.error('获取数据失败:', error);throw error; // 可以重新抛出错误} }
-
async/await 错误处理
// 方法1:try/catch async function getUser() {try {const user = await fetchUser();return user;} catch (error) {console.error('获取用户失败:', error);return null;} }// 方法2:catch 处理返回的 Promise async function getUser() {const user = await fetchUser().catch(error => {console.error('获取用户失败:', error);return null;});return user; }
四、Promise 与 async/await 对比
-
代码风格对比
// Promise 风格 function getData() {return fetchData().then(data => processData(data)).then(result => saveResult(result)).catch(error => handleError(error)); }// async/await 风格 async function getData() {try {const data = await fetchData();const result = await processData(data);return await saveResult(result);} catch (error) {handleError(error);} }
-
何时使用哪种?
- 使用 Promise:
- 需要同时处理多个异步操作(Promise.all/race)
- 需要精细控制 Promise 链
- 简单的单次异步操作
- 使用 async/await:
- 需要顺序执行的异步操作
- 需要更清晰的错误处理
- 代码可读性更重要时
五、常见问题与最佳实践
-
避免 await 滥用
// 错误:不必要的顺序执行 async function processItems(items) {for (const item of items) {await processItem(item); // 每个都等待,效率低} }// 正确:并行处理 async function processItems(items) {await Promise.all(items.map(item => processItem(item))); }
-
顶层 await
// 模块顶层可以使用 await const data = await fetchData(); console.log(data);// 注意:需要在 ES 模块中(type="module")
-
async 函数总是返回 Promise
async function foo() {return 'bar'; }console.log(foo()); // Promise {<fulfilled>: "bar"}
-
在循环中使用 await
// for...of 可以安全使用 await async function processArray(array) {for (const item of array) {await processItem(item);} }// 不要在 forEach 中使用 await array.forEach(async (item) => {await processItem(item); // 不会按预期工作 });
六、实际应用示例
-
带超时的 Promise
function fetchWithTimeout(url, timeout = 5000) {return Promise.race([fetch(url),new Promise((_, reject) => setTimeout(() => reject(new Error('请求超时')), timeout))]); }
-
顺序执行异步任务
async function executeSequentially(promises) {const results = [];for (const promise of promises) {results.push(await promise);}return results; }
-
重试机制
async function retry(fn, retries = 3, delay = 1000) {try {return await fn();} catch (error) {if (retries <= 0) throw error;await new Promise(resolve => setTimeout(resolve, delay));return retry(fn, retries - 1, delay * 2); // 指数退避} }
七、总结对比表
八、最佳实践建议
- 优先使用 async/await 编写更清晰的代码
- 合理使用 Promise 方法(如 all/race)处理并行任务
- 不要忘记错误处理,使用 try/catch 或 .catch()
- 避免不必要的 await,能并行就不要顺序执行
- 注意 Promise 创建时机,避免意外提前执行