JavaScript 中的 Async/Await 函数

front end technologyjavascriptobject oriented programming

处理异步任务对于网络编程至关重要。在 JavaScript 中,大多数情况下,我们请求的数据与系统不同步。要处理异步系统,我们可以在 JavaScript 中使用 Async 和 Await 函数。与函数一起使用的 async 关键字将使 JavaScript 函数成为异步函数。

异步函数

异步函数与 JavaScript 中的常规函数​​非常相似。语法如下− 从语法上看,很明显函数签名中只添加了'async'关键字。

语法

async function name(param1, param2, ...paramN) {
    // function body
}

示例

让我们看一个 javascript 中异步函数的简单示例。

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { async function myAsyncFunction() { content += "From Async function body" return Promise.resolve(1); } myAsyncFunction(); } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

从此示例输出中,我们看不出与正常函数输出有任何区别。但是当使用 async 关键字时,它会返回一个 promise 对象。有了这个 promise,我们可以应用方法链来使用 then() 函数。以下示例展示了这一点。

示例

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { async function myAsyncFunction() { content += "From Async function body" + '<br>' return Promise.resolve(1000); } myAsyncFunction().then(function (result) { content += result + "<br>" opDiv.innerHTML = content }); } catch (err) { error += err } finally { // display on output console .innerHTML = error } </script> </body> </html>

此示例与上一个示例类似,但它使用 then() 函数来检查函数是否已解析,如果已解析,则直接从中返回输出。

Await 关键字

在上一个示例中,我们看不到 async 函数的任何特殊操作,这是因为要查看 async 的效果,我们需要为异步系统设置环境。我们可以通过加入额外的延迟来实现这一点。在实际示例中,文件访问或从 Web 下载较大的文件将需要更长的时间,这将是异步的,在这种情况下,async 函数将变得方便。

要在一定持续时间后处理承诺,我们需要指定它必须等待一段时间。这样就可以使用 await 关键字。让我们看看语法和一些基本示例。

语法

let object = await <some promise>;

示例

让我们看一个 await 关键字的简单示例。

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { // Creating a promise let myPromise = new Promise(function (resolve, reject) { setTimeout(function () { resolve('Promise resolved') }, 4000); // resolve after 4 seconds }); // define one async function async function myAsyncFunction() { content += "Wait for some time..." + '<br>' opDiv.innerHTML = content // wait until the promise resolves let result = await myPromise; content += result + '<br>' content += 'The promise has been resolved' + '<br>' opDiv.innerHTML = content } myAsyncFunction(); } catch (err) { error += err } finally { // display on output console opErrDiv.innerHTML = error } </script> </body> </html>

直接查看此输出没有多大意义。如果您自己执行此代码,您会看到首先打印第一行"等待一段时间...",然后等待 4 秒(4000 毫秒)以生成下一个输出。这是因为我们创建了一个承诺,该承诺在 4 秒后解析并返回"Promise Resolved"字符串。

异步函数的错误处理

引发错误是异步函数的常见现象。例如,如果我们尝试从 Web 下载某个对象,它会通过承诺对象开始下载。但过了一段时间,出现了网络故障或权限问题或任何其他问题,因此这将无法成功完成其任务并引发错误。可以使用 catch() 或基本 try-catch 块直接处理此错误。

语法

asyncFunc().catch(
    // 处理来自异步函数的错误
)

示例

让我们看一个使用 promise 和异步函数时捕获错误的示例。

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { // Creating a promise function fetchUser(id) { if (typeof id !== 'number' || id <= 0) { throw new Error('ID is invalid, check again'); } return new Promise((resolve, reject) => { resolve({ id: id, username: 'someUser' }); }); } fetchUser('id1') .then(user => content += JSON.stringify(user.username)) .catch(err => error += err); } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

在上面的例子中,我们使用 .catch() 方法链捕获了一个错误。这将直接从承诺中检查错误。我们还可以从外部捕获和处理错误。这可以使用 javascript 中的异常处理方法 (try-catch) 语句来完成。

示例

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { // Creating a promise function fetchUser(id) { if (typeof id !== 'number' || id <= 0) { throw new Error('ID is invalid, check again'); } return new Promise((resolve, reject) => { resolve({ id: id, username: 'someUser' }); }); } try { fetchUser('id1') .then(user => content += JSON.stringify(user.username)) .catch(err => error += err); } catch (er) { error += er } } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

结论

处理异步任务是网络编程中最常见的任务之一。Javascript 使用 async 和 await 关键字将基本函数限定为异步函数。当我们从网络下载数据或读取与我们的系统不同步的大文件时,我们可以告诉编译器请不要在它工作时停止,它将在后台完成工作。完成后,执行代码中指定的其余操作。为此,async 和 await 关键字是 javascript 中最常用的功能。


相关文章