async
和 await
在现代JavaScript中,async
和 await
提供了一种更加简洁和直观的方式来处理异步操作。它们使得代码看起来更像同步代码,从而提高了可读性和维护性。
1) Promise ==> 异步操作的基础
Promise 是 JavaScript 中处理异步操作的一个重要概念,它代表了一个异步操作的最终完成(或失败)及其结果值。通过 Promise,我们可以更清晰地管理异步代码流,而不是使用传统的回调函数方式。
2) await ==> 将异步转为同步风格
await
可以看作是async wait
的缩写,它的主要作用是等待一个 Promise 对象被解决(resolved),从而使异步代码看起来更加同步。await
必须在async
函数内部使用,不能单独存在。它可以跟任何JavaScript表达式一起使用,但最常用于等待一个 Promise 对象。- 如果
await
后面跟着的是一个普通的表达式而非 Promise,则该表达式的值会被立即返回,不会造成等待。
3) async ==> 标识异步函数
- 当一个函数体内包含使用
await
的表达式时,这个函数必须用async
关键字声明。这样做会自动将该函数转换为异步函数,意味着它可以执行非阻塞的操作并返回一个 Promise 对象。 - 使用
async
定义的函数总是返回一个 Promise 对象,即使函数内部直接返回了一个普通值,该值也会被自动包装成一个已解决(fulfilled)的 Promise。
语法概览
-
定义一个异步函数:使用
async function
关键字来声明一个异步函数。async function fetchData() { // 异步操作... }
-
等待一个Promise:在异步函数内部,使用
await
来暂停执行直到 Promise 被解决(resolved)。注意,await
只能在异步函数内使用。const data = await fetchData();
实例演示
假设我们需要从API获取一些数据,并根据这些数据做进一步处理:
async function fetchAndProcessData() {
try {
let response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error('Network response was not ok');
let data = await response.json(); // 解析JSON数据
console.log(data);
} catch (error) {
console.error('Failed to fetch data:', error);
}
}
fetchAndProcessData();
在这个例子中,我们首先调用 fetch
函数发起网络请求。由于 fetch
返回的是一个 Promise,我们可以直接使用 await
来等待这个 Promise 完成。如果请求成功,我们会进一步解析响应体中的 JSON 数据;如果请求失败或遇到异常,会通过 catch
块捕获并处理错误。
注意点
-
await
只能在async
函数中使用:尝试在非异步函数中使用await
将会导致语法错误。 -
错误处理:当使用
await
时,推荐使用try...catch
结构来捕获可能的异常。因为异步函数内的任何未捕获的错误都会导致返回的 Promise 被拒绝。 -
并发执行:如果你有多个独立的异步任务需要同时执行,可以考虑使用
Promise.all()
来等待所有任务完成。这样可以提高性能,因为它允许任务并行运行。async function getData() { let [data1, data2] = await Promise.all([fetchData1(), fetchData2()]); console.log(data1, data2); }
-
理解返回值:记住,
async
函数总是返回一个 Promise。即使你在函数中直接返回了一个普通值,它也会被自动包装进一个已解决的 Promise 中。 -
调试:由于
await
暂停了函数的执行,这可能会给调试带来一定的复杂性。确保你理解每个await
的位置以及它如何影响代码的执行流程。