JavaScript 是一门单线程的语言,这意味着它无法同时处理多个任务。然而,在实际开发中,我们经常需要处理异步操作,比如网络请求、定时器、文件读取等。为了解决这些异步操作带来的复杂性,JavaScript 提供了多种方式,从最早的回调函数到现代的 Promise 和 Async/Await,逐步让异步代码更加优雅和易于维护。
本文将围绕 Promise 和 Async/Await 展开讨论,并结合实际开发中常用的 HTTP 客户端 Axios,为你展示如何高效地处理异步操作。
Promise
是一种异步编程的解决方案。它表示一个尚未完成的异步操作,以及未来可能产生的值。Promise
有三种状态:
pending
(进行中):初始状态,异步操作未完成。fulfilled
(已成功):操作成功,返回一个结果值。rejected
(已失败):操作失败,返回一个拒因。const promise = new Promise((resolve, reject) => {
const success = true; // 模拟操作结果
if (success) {
resolve("操作成功");
} else {
reject("操作失败");
}
});
promise
.then(result => {
console.log(result); // 输出: 操作成功
})
.catch(error => {
console.error(error); // 输出: 操作失败
});
Promise.all()
:等待所有 Promise 完成后返回一个包含结果的数组,如果有一个失败则返回失败。Promise.race()
:返回最先完成的 Promise 的结果(无论成功还是失败)。Promise.all([
axios.get('/api/data1'),
axios.get('/api/data2')
])
.then(responses => {
console.log('所有请求成功:', responses);
})
.catch(error => {
console.error('至少一个请求失败:', error);
});
Promise.race([
axios.get('/api/data1'),
axios.get('/api/data2')
])
.then(response => {
console.log('第一个请求完成:', response);
});
Async/Await
是 ES2017 引入的语法,用于简化基于 Promise 的异步操作,使得代码看起来像同步代码。
async
:声明一个函数为异步函数,该函数默认返回一个 Promise。await
:暂停异步函数的执行,直到 await
的 Promise 被解决,然后继续执行。async function fetchData() {
try {
const response = await axios.get('/api/data');
console.log('数据:', response.data);
} catch (error) {
console.error('请求失败:', error);
}
}
fetchData();
当异步任务需要按顺序执行时,使用 await
。
async function sequentialFetch() {
const response1 = await axios.get('/api/data1');
console.log('数据1:', response1.data);
const response2 = await axios.get('/api/data2');
console.log('数据2:', response2.data);
}
sequentialFetch();
使用 Promise.all()
可以并发执行多个异步任务,从而提高性能。
async function parallelFetch() {
const [data1, data2] = await Promise.all([
axios.get('/api/data1'),
axios.get('/api/data2')
]);
console.log('数据1:', data1.data);
console.log('数据2:', data2.data);
}
parallelFetch();
Axios 是一个基于 Promise 的 HTTP 客户端,可以用来发送网络请求。
axios.get('/api/data')
.then(response => {
console.log('数据:', response.data);
})
.catch(error => {
console.error('请求失败:', error);
});
将 Axios 与 async/await
结合,可以使代码更加简洁。
async function getData() {
try {
const response = await axios.get('/api/data');
console.log('数据:', response.data);
} catch (error) {
console.error('请求失败:', error);
}
}
getData();
结合 Promise.all()
,可以同时发送多个请求,并等待所有请求完成。
async function fetchMultipleData() {
try {
const [data1, data2] = await Promise.all([
axios.get('/api/data1'),
axios.get('/api/data2')
]);
console.log('数据1:', data1.data);
console.log('数据2:', data2.data);
} catch (error) {
console.error('请求失败:', error);
}
}
fetchMultipleData();
使用 try...catch
捕获异步操作中的错误,或者通过 Axios 的拦截器统一处理。
async function fetchData() {
try {
const response = await axios.get('/api/data');
console.log('数据:', response.data);
} catch (error) {
if (error.response) {
console.error('服务器错误:', error.response.status);
} else {
console.error('请求失败:', error.message);
}
}
}
axios.interceptors.response.use(
response => response,
error => {
console.error('全局拦截器捕获错误:', error.message);
return Promise.reject(error);
}
);
Promise 和 Async/Await 的选择
Promise
更适合。Async/Await
更清晰。错误处理
性能优化
Promise.all()
)。通过熟练掌握 Promise、Async/Await 和 Axios 的使用,你可以写出更加优雅、简洁且高效的异步代码。希望本文能够帮助你更深入地理解异步开发的核心理念与实践技巧!