将 Promise 的链式调用改为 async/await 可以使代码更加清晰和易于理解。下面我会展示几种常见的转换示例:
基本转换示例
Promise 链式调用
function fetchData() {
return fetch('/api/data')
.then(response => response.json())
.then(data => processData(data))
.then(result => {
console.log(result);
return result;
})
.catch(error => {
console.error('Error:', error);
throw error;
});
}
对应的 async/await 写法
async function fetchData() {
try {
const response = await fetch('/api/data');
const data = await response.json();
const result = await processData(data);
console.log(result);
return result;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
多个独立 Promise 的并行处理
Promise.all 链式调用
function fetchMultiple() {
return Promise.all([fetch('/api/data1'), fetch('/api/data2')])
.then(([response1, response2]) => {
return Promise.all([response1.json(), response2.json()]);
})
.then(([data1, data2]) => {
return { data1, data2 };
});
}
对应的 async/await 写法
async function fetchMultiple() {
const [response1, response2] = await Promise.all([
fetch('/api/data1'),
fetch('/api/data2')
]);
const [data1, data2] = await Promise.all([
response1.json(),
response2.json()
]);
return { data1, data2 };
}
复杂链式调用的转换
复杂 Promise 链
function complexOperation() {
return getUser()
.then(user => getPermissions(user))
.then(permissions => {
if (permissions.admin) {
return getAdminData()
.then(data => ({ data, role: 'admin' }));
} else {
return getRegularData()
.then(data => ({ data, role: 'regular' }));
}
})
.then(result => {
return logResult(result)
.then(() => result);
});
}
对应的 async/await 写法
async function complexOperation() {
const user = await getUser();
const permissions = await getPermissions(user);
let result;
if (permissions.admin) {
const data = await getAdminData();
result = { data, role: 'admin' };
} else {
const data = await getRegularData();
result = { data, role: 'regular' };
}
await logResult(result);
return result;
}
注意事项
- 错误处理:async/await 需要使用 try/catch 来处理错误,而不是 .catch()
- 并行执行:对于可以并行执行的 Promise,仍然应该使用 Promise.all
- 返回值:async 函数总是返回一个 Promise,即使你没有显式返回 Promise
- 顶层 await:在模块顶层可以使用 await(ES2022+),但在普通脚本中不行
async/await 让异步代码看起来更像同步代码,提高了可读性和可维护性。