在 JavaScript 的发展历程中,回调地狱和异步编程一直是个让前端开发者头疼的问题。随着 ES7 中的 async/await
异步函数的普及,前端开发变得更加容易。在 ES9 中,async/await
获得了更进一步的升级。本文将为大家讲解 ES9 中的 async/await
实现原理及其错误处理方法。
async/await 简介
async/await
是 ES7 引入的 JavaScript 异步编程解决方案,能够显式地将异步操作转换成同步代码的形式。async/await
基于 Promise 机制,简化了 Promise 的写法,并且可以在不阻塞程序的情况下等待 Promise 返回。它允许程序员通过暂停和恢复异步函数执行的方式编写直观的代码,以及通过非常简单的同步编程模型来解决常见的异步问题。
async/await 基础语法
async/await
的语法极其简单。在函数声明前面加上 async
关键字,表示该函数内部会有异步操作,函数内部使用 await
操作符等待异步操作的结果。
下面是一个返回 Promise 的异步函数,以及使用 async/await
语法写的示例代码:
-- -------------------- ---- ------- -------- ----------- - ------ --- --------------- -- - ------------- -- - --------------- --------- -- ------ --- - ----- -------- ------ - ----- ---- - ----- ------------ ------------------ -- --------- ------ - -------
在 main
函数内使用了 async/await
语法,以同步的方式使用 fetchData
函数。首先在 fetchData
中使用 setTimeout
模拟异步操作,等待 1 秒后返回 Promise。在 main
函数中,使用 await
操作符等待 fetchData
函数的返回结果,并将结果赋值给 data
变量。之后输出结果。
async/await 错误处理
由于 async/await
基于 Promise,因此我们可以使用 Promise 的错误处理方式处理异步中的错误。可以使用 try
和 catch
语句块来捕获 Promise 异常。示例代码如下:
-- -------------------- ---- ------- -------- ----------- - ------ --- ----------------- ------- -- - ------------- -- - ---------- ------------- -- ----- -------- -- ------ --- - ----- -------- ------ - --- - ----- ---- - ----- ------------ - ----- ------- - ------------------- -- --- ------ ------ -- ----- ---- - - -------
fetchData
函数返回的 Promise 在 1 秒后将会被拒绝(reject)。在 main
函数中使用 try...catch
语句来捕获异常。当 fetchData
函数抛出错误时,错误将被捕获并在控制台中打印。
实现原理
了解了 async/await
的语法和错误处理方法之后,我们来看看它是如何实现的。
其实,async/await
仍然建立在 Promise 基础之上,只是使用了 Generator 函数。Generator 函数提供了一种返回值之间交替执行顺序的方法。而 await
操作符就是在 Generator 函数的基础上打了一个包装。 async function
创建一个异步的函数,返回值是一个 Promise 对象。当此函数执行时,返回的结果是一个 Promise 对象,可以使用 then
或者 catch
方法获取返回值。
下面是一个使用 Generator 函数模拟实现 await
的代码:
-- -------------------- ---- ------- -------- ------------------------------- - ------ ---------- - ----- --------- - ------------------------- ----------- ------ --- ----------------- ------- -- - -------- --------- ---- - --- --------------- - ----- --- - -- -- --------- -- --------------- - -------------------- - ----- ----- - ------------ - ----- - ------ ---- - - ---------------- -- ------ - --------------- - ---- - -- -- ------- ------ ---------------------------- --------------- - ------------ ------- -- --------------- - ------------- ------- - -- - - ------------- --- -- - -------- ----------- - ------ --- ----------------- -- - ------------- -- - --------------- --------- -- ------ --- - ----- --------- - -------------------------- ------ - ----- ---- - ----- ------------ ------------------ -- --------- ------ ----- ------ - ----- --------------------- -------------------- -- ------ --- ------------
在上述代码中,我们获得了一个传入 Generator 函数 generatorFunc
的参数,并将其作为 this 上下文调用。我们创建了一个 step
方法,其中接收一个参数 key
和另一个 arg
参数。通过 generator[key](arg)
调用 Generator 函数并执行,如果产生异常则通过 reject 函数被捕获。
如果没有异常,我们解析生成器结果,并从 value
继续执行或执行 catch函数。如果 done 尚未采用,我们将通过执行return Promise.resolve(value).then(...)
返回一个已解决(resloved)的 Promise, 然后回到 step('next', reslovedValue)
并开始执行yield下一个返回值。
结论
本文介绍了 ES9 中的 async/await
实现原理及其错误处理方法。我们了解了 async/await
的基础语法,并使用示例代码演示了错误处理方法。最后,我们通过代码实现了一个简单的 async/await
模拟版本。希望本文能够帮助你更好地理解异步编程和 ES9 中的 async/await
的实现原理。
参考资料
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/670e297c5f551281025fdebb