当然可以!async
和 await
是 JavaScript 中用于简化 异步编程 的语法糖,它们构建在 Promise 之上,能让异步代码写起来像同步代码一样清晰。
✨ 一句话理解
async
用于声明一个异步函数,这个函数总是返回一个Promise
。await
用于等待一个 Promise 的结果,只能在async
函数内部使用。
🔧 1. async 函数
async function foo() {
return 42;
}
上面的 foo()
实际上等价于:
function foo() {
return Promise.resolve(42);
}
你可以这样调用它:
foo().then(value => {
console.log(value); // 输出 42
});
🕓 2. await 用法
await
可以暂停 async
函数的执行,直到 Promise
执行完成,返回其结果。
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function example() {
console.log('开始');
await delay(1000); // 等待 1 秒
console.log('1 秒后继续');
}
⚡ 示例:请求数据的对比
✅ 使用 async/await(简洁清晰)
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('发生错误:', error);
}
}
❌ 等价的 Promise 写法(回调嵌套多)
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error('发生错误:', error);
});
📌 3. async/await 的规则总结
规则 | 说明 |
---|---|
只能在 async 函数内部使用 await | 否则会报错 |
async 函数总是返回一个 Promise | 即使你返回的是普通值 |
await 等待的是一个 Promise | 如果不是 Promise,也会自动转换成已完成的 Promise |
可以用 try/catch 捕获异常 | 更易读 |
🔁 4. 多个异步串行和并行的对比
串行执行(等待上一个执行完)
await doTask1(); // 等待执行完
await doTask2(); // 等待执行完
并行执行(同时发起)
const [res1, res2] = await Promise.all([doTask1(), doTask2()]);
❗ 错误处理建议
用 try/catch
包住 await
,能更优雅地处理错误:
async function safeCall() {
try {
const data = await fetchData();
console.log(data);
} catch (e) {
console.error('请求失败:', e);
}
}
🧠 总结记忆口诀
async 返回 Promise,await 等待 Promise。
能让异步写法像同步,看起来更清晰。
只能在 async 函数中用 await,不要在全局乱用。
🚀 拓展阅读
Promise.all
/Promise.race
与await
配合- 顶层 await(ES2022 支持)
- async 递归、并发控制等高级用法
好的!以下是一个完整的 async/await 异步请求实战案例,涵盖:
- 异步请求接口数据
- 错误处理(try/catch)
- 并发请求(
Promise.all
) - 请求失败自动重试机制(进阶)
✅ 场景说明
假设我们要请求一个用户 API,比如:
https://jsonplaceholder.typicode.com/users/1
https://jsonplaceholder.typicode.com/users/2
- 等等…
我们希望:
- 支持并发请求多个用户数据
- 如果有请求失败,能够优雅地处理
- 支持失败自动重试(可选)
🧩 完整代码示例(浏览器可直接运行)
// 一个延时函数(模拟网络延迟)
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 获取单个用户信息(带错误处理)
async function fetchUser(userId) {
const url = `https://jsonplaceholder.typicode.com/users/${userId}`;
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`用户 ${userId} 请求失败,状态码: ${response.status}`);
}
const data = await response.json();
console.log(`✅ 用户 ${userId} 数据:`, data);
return data;
} catch (error) {
console.error(`❌ 获取用户 ${userId} 失败:`, error.message);
return null;
}
}
// 批量获取多个用户信息(并发 + 错误处理)
async function fetchMultipleUsers(userIds) {
const promises = userIds.map(id => fetchUser(id));
const results = await Promise.all(promises); // 并发请求
const successful = results.filter(user => user !== null);
console.log(`🎉 成功获取了 ${successful.length} 个用户数据`);
}
// 可选进阶:支持失败自动重试(最多重试 3 次)
async function fetchWithRetry(fn, retries = 3, delayMs = 1000) {
for (let i = 0; i <= retries; i++) {
try {
return await fn();
} catch (err) {
console.warn(`⚠️ 第 ${i + 1} 次尝试失败: ${err.message}`);
if (i < retries) {
await delay(delayMs);
} else {
throw err;
}
}
}
}
// 使用示例
(async () => {
const userIds = [1, 2, 3, 999]; // 999 是故意让一个失败
console.log('📡 开始请求多个用户信息...');
await fetchMultipleUsers(userIds);
})();
🧠 你学到的核心知识点:
技术点 | 示例 |
---|---|
async/await | 用于异步操作流程化 |
try/catch | 捕获请求异常 |
Promise.all | 多个异步任务并发处理 |
自定义封装 fetchWithRetry | 异常重试机制 |
发表回复