Appearance
十二、async / await(异步终极方案)
async/await 是 ES8 引入的异步编程语法糖,它基于 Promise,使异步代码看起来更像同步代码,更加清晰易读。
什么是 async / await?
- async:用于声明一个函数是异步的,返回一个 Promise
- await:用于等待一个 Promise 完成,只能在 async 函数中使用
基础用法
基本语法
javascript
// 定义异步函数
async function fetchData() {
// 等待 Promise 完成
const result = await new Promise(resolve => {
setTimeout(() => resolve('数据'), 1000);
});
console.log(result); // 数据
return result;
}
// 调用异步函数
fetchData().then(data => {
console.log('异步函数返回:', data); // 异步函数返回: 数据
});与 Promise 结合
javascript
// 模拟 API 请求
function fetchUser() {
return new Promise(resolve => {
setTimeout(() => resolve({ id: 1, name: 'John' }), 1000);
});
}
function fetchPosts(userId) {
return new Promise(resolve => {
setTimeout(() => resolve([
{ id: 1, title: 'Post 1' },
{ id: 2, title: 'Post 2' }
]), 1000);
});
}
// 使用 async/await
async function getUserPosts() {
try {
// 等待获取用户
const user = await fetchUser();
console.log('用户:', user);
// 等待获取帖子
const posts = await fetchPosts(user.id);
console.log('帖子:', posts);
return { user, posts };
} catch (error) {
console.error('错误:', error);
}
}
getUserPosts().then(result => {
console.log('结果:', result);
});错误处理
try/catch
javascript
async function fetchData() {
try {
const result = await new Promise((resolve, reject) => {
setTimeout(() => reject('出错了'), 1000);
});
console.log(result);
} catch (error) {
console.error('捕获到错误:', error); // 捕获到错误: 出错了
}
}
fetchData();外部捕获
javascript
async function fetchData() {
const result = await new Promise((resolve, reject) => {
setTimeout(() => reject('出错了'), 1000);
});
return result;
}
fetchData()
.then(result => console.log(result))
.catch(error => console.error('捕获到错误:', error)); // 捕获到错误: 出错了结合 Promise 使用
并发请求
javascript
async function fetchAllData() {
// 同时发起多个请求
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(1),
fetchComments(1)
]);
console.log('用户:', user);
console.log('帖子:', posts);
console.log('评论:', comments);
return { user, posts, comments };
}
fetchAllData();处理多个异步操作
javascript
async function processData() {
// 顺序执行
const data1 = await fetchData1();
const data2 = await fetchData2(data1);
const data3 = await fetchData3(data2);
return data3;
}
processData().then(result => {
console.log('最终结果:', result);
});实战:模拟异步获取数据
javascript
// 模拟 API 请求
function fetchData(url) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`Fetching from ${url}`);
resolve(`Data from ${url}`);
}, Math.random() * 1000);
});
}
// 使用 async/await
async function getData() {
try {
console.log('开始获取数据...');
// 并发请求
const [users, posts, comments] = await Promise.all([
fetchData('https://api.example.com/users'),
fetchData('https://api.example.com/posts'),
fetchData('https://api.example.com/comments')
]);
console.log('获取数据完成');
console.log('用户数据:', users);
console.log('帖子数据:', posts);
console.log('评论数据:', comments);
return { users, posts, comments };
} catch (error) {
console.error('获取数据失败:', error);
}
}
getData().then(result => {
console.log('最终结果:', result);
});async/await 的优势
- 代码简洁:使异步代码看起来更像同步代码
- 可读性高:逻辑流程清晰明了
- 错误处理简单:可以使用 try/catch 进行错误处理
- 易于调试:调试时可以设置断点,一步一步执行
- 与 Promise 兼容:完全基于 Promise,可以与 Promise 无缝配合
异步编程发展历程
- 回调函数:最早的异步处理方式,容易形成回调地狱
- Promise:解决了回调地狱问题,提供了链式调用
- async/await:基于 Promise,使代码更加简洁易读
对比
javascript
// 回调地狱
function callbackHell() {
step1(function(result1) {
step2(result1, function(result2) {
step3(result2, function(result3) {
console.log(result3);
});
});
});
}
// Promise
function promiseChain() {
step1()
.then(result1 => step2(result1))
.then(result2 => step3(result2))
.then(result3 => console.log(result3))
.catch(error => console.error(error));
}
// async/await
async function asyncAwait() {
try {
const result1 = await step1();
const result2 = await step2(result1);
const result3 = await step3(result2);
console.log(result3);
} catch (error) {
console.error(error);
}
}通过本章节的学习,你已经掌握了 async/await 的基本用法和优势。async/await 是目前最流行的异步编程方式,它使异步代码更加简洁易读,提高了开发效率。
