在 JavaScript 中,async
和 Promise
都用于处理异步操作,但它们的用法和语法有一些显著区别。以下是它们的详细对比:
1. 基本定义
Promise
Promise
是一个表示异步操作最终结果的对象。- 它有三种状态:
pending
(进行中)fulfilled
(已完成)rejected
(已拒绝)
- 使用
.then()
和.catch()
处理异步结果。
const promiseExample = new Promise((resolve, reject) => {
setTimeout(() => resolve("Success!"), 1000);
});
promiseExample.then(console.log).catch(console.error);
async
async
是一种语法糖,用于定义返回Promise
的函数。- 异步代码看起来更像同步代码。
- 配合
await
使用,可以暂停代码执行,直到Promise
被解决。
async function asyncExample() {
return "Success!";
}
asyncExample().then(console.log).catch(console.error);
2. 语法对比
Promise
使用 Promise
通常需要嵌套 .then()
或链式调用,可能会导致代码可读性较差。
const promiseExample = () => {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("Data fetched"), 1000);
});
};
promiseExample()
.then((result) => {
console.log(result);
return "Next Step";
})
.then(console.log)
.catch(console.error);
async/await
async/await
让代码看起来更线性和清晰,但需要在 async
函数中使用。
const asyncExample = async () => {
try {
const result = await new Promise((resolve) => {
setTimeout(() => resolve("Data fetched"), 1000);
});
console.log(result);
return "Next Step";
} catch (error) {
console.error(error);
}
};
asyncExample();
3. 错误处理
Promise
使用 .catch()
捕获错误:
const promiseWithError = () => {
return new Promise((resolve, reject) => {
setTimeout(() => reject("Something went wrong!"), 1000);
});
};
promiseWithError()
.then(console.log)
.catch(console.error); // 捕获错误
async/await
使用 try...catch
捕获错误:
const asyncWithError = async () => {
try {
const result = await new Promise((_, reject) => {
setTimeout(() => reject("Something went wrong!"), 1000);
});
console.log(result);
} catch (error) {
console.error(error); // 捕获错误
}
};
asyncWithError();
4. 嵌套问题
Promise
嵌套多个异步操作时可能会导致代码复杂化。
const fetchData = () => Promise.resolve("Data fetched");
const processData = (data) => Promise.resolve(`${data} processed`);
fetchData()
.then((data) => {
return processData(data);
})
.then((processedData) => {
console.log(processedData);
})
.catch(console.error);
async/await
async/await
避免了嵌套,让代码更简洁。
const fetchData = () => Promise.resolve("Data fetched");
const processData = (data) => Promise.resolve(`${data} processed`);
const asyncWorkflow = async () => {
try {
const data = await fetchData();
const processedData = await processData(data);
console.log(processedData);
} catch (error) {
console.error(error);
}
};
asyncWorkflow();
5. 并发操作
Promise
可以使用 Promise.all
处理并发任务:
const task1 = () => Promise.resolve("Task 1 complete");
const task2 = () => Promise.resolve("Task 2 complete");
Promise.all([task1(), task2()]).then(console.log);
async/await
在 async
函数中也可以使用 Promise.all
处理并发任务:
const task1 = () => Promise.resolve("Task 1 complete");
const task2 = () => Promise.resolve("Task 2 complete");
const asyncConcurrent = async () => {
const results = await Promise.all([task1(), task2()]);
console.log(results);
};
asyncConcurrent();
6. 返回值
Promise
Promise
的返回值需要通过 .then()
获取。
const promiseExample = () => Promise.resolve("Data fetched");
promiseExample().then(console.log);
async
async
函数的返回值本质上是一个 Promise
,可以通过 .then()
或 await
获取。
const asyncExample = async () => "Data fetched";
asyncExample().then(console.log);
总结对比
特性 | Promise | async/await |
---|---|---|
定义 | 异步操作的核心 API | Promise 的语法糖 |
可读性 | 链式调用可能导致复杂代码 | 更接近同步代码,可读性强 |
错误处理 | .catch() | try...catch |
并发处理 | 使用 Promise.all | 结合 Promise.all 或多个 await |
嵌套问题 | 可能出现链式嵌套 | 避免嵌套,更清晰 |
返回值 | 直接返回 Promise 对象 | 返回 Promise ,但看起来像返回普通值 |
何时使用?
- 使用
Promise
: 当你需要处理简单的异步任务或链式调用时。 - 使用
async/await
: 当你需要编写复杂的异步逻辑,且希望代码更直观时。