异步编程是现代前端开发中不可避免的技术要素,它的出现是为了解决 JavaScript 单线程的限制,可以更好的处理好页面渲染以及用户交互体验等问题。在 ES8 中,异步编程有了更为便捷的实现方式:Async/Await。
什么是 Async/Await
Async/Await 是 ES8 中新增的异步编程方式,它是对 Promise 的一层封装。通过 Async 函数和 Await 表达式,可以更加轻松地实现异步编程。所谓 “Async” 即异步的意思,“Await” 即等待的意思。
Async/Await 的使用方法
- 定义 Async 方法
Async 方法需要用 async
关键字来修饰,其可以不加参数,也可以加上请求所需参数。
- Await 表达式
Await 表达式是 Async 函数中的语句,在这里可以暂停 Async 方法的执行,直到 Await 表达式的 Promise 对象是 resolved。如果 Promise 返回的 status 是 rejected,则会抛出异常。可以将 Await 表达式赋值给一个变量,以便后续处理。
下面是一个使用 Async/Await 的示例代码:
async function foo() { try { const result = await promise; console.log(result); } catch (error) { console.error(error); } } foo();
Async/Await 的实现原理
Async/Await 的实现原理基于 Generator,也就是说,Async 函数是 Generator 函数的语法糖。
- Async 函数通过返回一个 Promise 对象来实现异步操作
在 Async 函数的内部实现,它通过 Generator 函数来实现异步操作,返回值是一个 Promise 对象。
下面是一个 Async 函数的示例代码:
async function bar() { const result = await fakeRequest('/data.json'); return result; } bar().then(result => console.log(result));
- 使用 Generator 函数来实现异步操作
当我们在 Async 函数使用 await
表达式的时候,就相当于 Yield 表达式的效果,表明等待异步操作完成。当其完成之后,再将结果作为结果对象的属性值,再调用 Generator 函数的 next 方法。
异步操作的状态是 Promise 对象实现的,Generator 函数有两个重要性质:
1. 自动执行; 2. 第一次调用 next 方法时,就会执行到第一个 yield 表达式,等待 Promise 对象状态的改变。
下面是一个基于 Generator 的异步编程示例代码:
function* foo() { const result = yield request('/data.json'); console.log(result); } function request(url) { return fetch(url).then(response => response.json()); } const iterator = foo(); const promise = iterator.next().value; promise.then(result => iterator.next(result));
Async/Await 的优化方法
虽然 Async/Await 语法更加简洁,但是在使用过程中,我们依然需要注意一些优化方法,以提高代码的性能和可维护性。
1. 处理错误的方式
在 Async 函数中使用 try-catch
来处理错误,可以更加直观地了解哪个异步函数返回了错误。
async function foo() { try { const result = await promise; console.log(result); } catch (error) { console.error('Error:', error); } } foo();
2. 并发请求(Promise.all)
如果有多个异步请求需要被处理,可以通过 Promise.all
对它们进行处理。这个方法接受一个包含多个 Promise 实例的数组,当所有的 Promise 都完成之后,将返回所有 Promise 对象的值的数组,以便后续处理。
下面是一个并发请求的示例代码:
async function foo() { try { const [result1, result2] = await Promise.all([ promise1, promise2, ]); console.log(result1, result2); } catch (error) { console.error('Error:', error); } } foo();
3. Async 函数串行执行
在异步编程中,有时候我们需要一些异步操作按顺序执行,可以使用在每个异步操作之间添加 await
表达式的方式,以便实现串行执行的效果。
下面是一个异步函数串行执行的示例代码:
async function foo() { try { const result1 = await request('/data.json'); console.log(result1); const result2 = await request('/data2.json'); console.log(result2); } catch (error) { console.error('Error:', error); } } foo();
总结
Async/Await 是一种相对传统的 Promise 的简洁写法,能够让我们更加方便的实现异步编程,同时需要注意优化性能和代码可维护性。熟练掌握它的语法以及实现原理,可以更好地编写高质量的异步代码。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a76633add4f0e0ff07383b