JavaScript的异步编程已经成为前端开发中的必备技术。之前的回调地狱和Promise都有许多不足之处,使得我们需要更好的解决方案。从ES2017开始,JavaScript添加了一种非常优雅的语法:async和await。它们强制异步编程始终返回一个promise,帮助我们保持代码的可读性和可维护性,并使我们可以轻松地处理异步任务。
Async 和 Await
Async和Await是JavaScript中处理异步操作的语法糖。他们让我们写异步代码的方式更加接近于同步代码,让代码的可读性更好,也让我们更容易地处理异步任务。Async和Await实际上是Promise的进一步封装。
Async
Async函数是异步函数的一种简化写法,让我们可以写出一个用起来像同步函数(并且代码非常简洁易懂)的异步函数。如果我们在一个函数的声明前加上关键字async,则我们可以在函数体内使用await。
async function foo() { return "Hello, Async!"; }
这里我们声明了一个函数foo,它是一个异步函数。异步函数返回一个promise,我们可以使用then()或await来处理异步操作的结果。上面的示例会返回一个包含字符串“Hello,Async!”的promise。
Await
Await是一个操作符,让我们在一个异步函数内等待一个Promise(或其它等待某种异步操作完成的变量或函数)完成,然后得到异步操作的结果。
async function foo() { const result = await someAsyncFunction(); console.log(result); }
在上述示例中,我们首先声明了一个异步函数foo,然后使用await等待一个异步操作执行完毕(在这里,可能是一个Promise对象)并返回其结果,然后使用result变量来接收异步操作的结果。
需要注意的是,await只能在异步函数中使用。如果我们试图在同步函数中使用它,JavaScript会抛出一个编译时错误。我们在同步函数中使用await的场景通常是需要等待其他异步函数结果再继续执行的情况下。
在使用async/await时,我们可以使用try/catch来处理异步操作抛出的异常。
使用 Async 和 Await 处理异步操作
下面我们来看一个使用Async和Await的例子,更好地理解如何使用它们处理异步操作。
const fetchUserData = async (userId) => { const userResponse = await fetch(`/user/${userId}`); const userData = await userResponse.json(); const userAvatarResponse = await fetch(`/user/${userId}/avatar`); const userAvatarData = await userAvatarResponse.json(); return { ...userData, ...userAvatarData }; };
在上述示例中,我们定义了一个名为fetchUserData的异步函数。这个函数首先使用fetch函数来获取指定的用户ID的用户数据,然后使用await等待异步操作完成。接着获取用户数据的服务器响应,使用json()异步方法将其转换为JSON格式。在转换需要时间期间,JavaScript不会阻塞并像同步方式一样执行后续代码。换句话说,当所有异步操作完成后,fetchUserData函数会返回一个包含合并用户数据和用户头像数据的对象。
处理多个异步操作
我们可以处理多个异步操作(同时等待这些操作完成)并在完成后执行一些操作。例如,我们有一个获取多个用户ID的函数,我们想从服务器获取每个用户的头像和个人资料数据,然后在获取到所有数据后执行一些操作。
const fetchUserDetails = async (userIds) => { const requests = userIds.map((userId) => fetchUserData(userId)); const users = await Promise.all(requests); console.log(users); };
在上述示例中,我们首先将每个user ID映射到一个异步函数fetchUserData,这个函数会返回一个promise,其中包含相应用户的个人资料和头像数据。使用map()来让映射成为一个用户数据promise数组,代表所有要获取的用户资料与头像数据的promise数组加以处理。接着我们使用Promise.all()等待所有的promise完成(即等待所有用户的数据都成功获取)。在Promise.all()的结果中,我们会拿到一个类似于一个数组的结果,其中包含所有结果。
总结
Async和Await是JavaScript中强大的异步编程语法糖。他们能够让我们处理异步操作和代码变得更简洁和易懂。 我们可以使用async和await来使用Promise管理异步操作。在实际场景中,我们使用async和await进行异步编程操作,能够让我们的代码更加接近于同步代码的形式,使得异步编程的代码更加易读和更容易调试。
示例代码
最后,我们提供一份完整的使用示例代码:
-- -------------------- ---- ------- ----- ------------- - ----- -------- -- - ----- ------------ - ----- ------------------------- ----- -------- - ----- -------------------- ----- ------------------ - ----- -------------------------------- ----- -------------- - ----- -------------------------- ------ - ------------ ----------------- -- -- ----- ---------------- - ----- --------- -- - ----- -------- - -------------------- -- ----------------------- ----- ----- - ----- ---------------------- ------------------- -- ------------------------------
在上述代码示例中,我们使用了fetchUserData和fetchUserDetails两个异步操作处理函数进行演示。fetchUserDetails函数提供一个用户ID数组参数,用以获取所有用户数据。fetchUserData函数用于获取指定用户的数据(具体分为个人资料和头像数据),我们会使用fetch()和await来处理异步请求,使用json()方法将响应转换为JSON格式。最后我们使用fetchUserDetails函数获取用户数组,等待所有异步promise完成,并将结果打印到日志中。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/645b0a66968c7c53b0d66e46