JavaScript - 异步/等待



使用async/await关键字定义的 JavaScript 函数可以执行与 Promise 相同的任务,但代码行数更少,并且使代码更易读。Promise 的语法有点复杂,因此引入了 async/await 语法。

要使用 async/await,我们首先需要定义一个 async 函数。为此,我们在函数定义之前编写 async。async 函数返回一个 Promise。await 关键字仅在 async 函数内部使用。await 关键字使 JavaScript 等待 Promise 解析,然后继续执行函数。

让我们分别详细了解 async/await 关键字 -

JavaScript Async 关键字

使用 async 关键字定义的 JavaScript 函数称为异步函数。async 函数允许你生成异步代码。

它始终返回 Promise。如果你没有手动返回 Promise 并返回数据、字符串、数字等,它会创建一个新的 Promise 并使用返回值解析该 Promise。

语法

你可以使用以下语法在 JavaScript 中使用 async 关键字定义函数 -

async function func_name(parameters) {
   // function body
}

在以上语法中,我们在函数名称之前使用了 'async' 关键字。

参数

  • Func_name - 它是函数名称的有效标识符。
  • Parameters - 它接受多个参数,与普通函数相同。

查看下面的异步函数,它返回“hello world”文本。它返回包含“hello world”成功消息的 Promise。

async function printMessage() {
   return "Hello World";
}

以下代码与以上代码类似。

function printMessage() {
   return Promise.resolve("Hello World");
}

你可以使用 then() 和 catch() 方法来解决异步函数返回的 Promise。

示例

我们在下面的代码中从 getText() 函数返回文本。

之后,我们使用 then() 和 catch() 方法以及 getText() 方法的执行来使用 getText() 函数返回的 Promise。

在这里,你可以观察到我们从异步函数返回了文本,但它正在返回 Promise。

<html>
<body>
   <div id = "output"> </div>
   <script>
      async function getText() {
         return "Text from the getText() function.";
      }
      getText().then((text) => {
         document.getElementById('output').innerHTML = text + "<br>";
      }).catch((err) => {
         document.getElementById('output').innerHTML += JSON.stringify(err);
      });
   </script>
</body>
</html>

输出

Text from the getText() function.

JavaScript Await 关键字

你只能在 JavaScript 异步函数内部使用“await”关键字。它会暂停函数的执行,直到 Promise 完成,这意味着它被拒绝或已完成。

语法

以下是 JavaScript 中在异步函数内部使用“await”关键字的语法 -

async function func_name(parameters) {
   await promise;
   // Function body
}

在以上语法中,我们在“async”函数内部使用了“await”关键字。

示例

我们在下面的代码中定义了 solvePromise() 异步函数。我们在函数中使用 Promise() 构造函数创建了新的 Promise。之后,我们使用 Promise 以及“await”关键字来解析它,而不是使用 then() 或 catch() 方法。

在输出中,你可以看到它打印了完成消息。

<html>
<body>
   <div id = "output">The resultant value from the promise is:</div>
   <script>
      async function solvePromise() {
         const promise = new Promise((resolve, reject) => {
            resolve('Promise is solved');
         })
         const result = await promise;
         document.getElementById('output').innerHTML += result;
      }
      solvePromise();
   </script>
</body>
</html>

输出

The resultant value from the promise is: Promise is solved

示例(等待超时)

在下面的代码中,我们使用 setTimeOut() 方法设置了 2000 毫秒的超时时间来解决 Promise。

之后,我们使用 ‘await’ 关键字与 Promise 一起,暂停函数的执行,直到 Promise 完成。在输出中,您可以看到它在 2 秒后打印了 Promise 返回的消息。

<html>
<body>
   <div id = "output">The promise is being solved <br> </div>
   <script>
      async function solvePromise() {
         const promise = new Promise((resolve, reject) => {
            setTimeout(() => { // Setting up timeout for promises
               resolve('The promise is solved after 2 seconds');
            }, 2000);
         })
         const result = await promise;
         document.getElementById('output').innerHTML += result;
      }
      solvePromise();
   </script>
</body>
</html>

输出

The promise is being solved
The promise is solved after 2 seconds

JavaScript Async/Await 的错误处理

在使用 Promise 时,我们使用 then() 和 catch() 方法来处理数据和错误。

使用异步函数,您可以使用 try…catch 块来处理错误。

当 Promise 成功 fulfilled 时,控制权会执行 ‘try’ 块的剩余代码。否则,它会执行 ‘catch’ 块的代码来修复错误。

语法

以下是处理异步函数中错误的语法:

try {
   const result = await promise;
   // Manipulate data
} catch (err) {
   // Handle errors
}

我们需要在 ‘try’ 块中使用 Promise,并在 ‘catch’ 块中处理错误。catch() 方法也以 ‘err’ 作为参数,它是一个 Promise 拒绝消息或错误对象。

示例

在下面的代码中,我们定义了一个 Promise 并将其拒绝。

之后,我们在 ‘try’ 块中使用 Promise。由于 Promise 被拒绝,执行控制权将进入 ‘catch’ 块并打印拒绝消息。

<html>
<body>
   <div id = "demo"> </div>
   <script>
      let output = document.getElementById('demo');
      async function solvePromise() {
         const promise = new Promise((resolve, reject) => {
            reject("The promise is rejected");
         })
         try {
            const result = await promise;
            output.innerHTML += "Inside the try block. <br>";
            output.innerHTML += result;
         } catch (err) {
            output.innerHTML += "Inside the catch block. <br>";
            output.innerHTML += err;
         }
      }
      solvePromise();
   </script>
</body>
</html>

输出

Inside the catch block.
The promise is rejected

JavaScript Async 类方法

您还可以使用 ‘async’ 关键字定义异步类方法来处理异步操作。

它与异步函数具有相同的语法。

语法

以下是使用 JavaScript 中类方法的 async/await 的语法:

async method_name() {
   return await promise;
}

在上述语法中,method_name 是类方法的标识符,它使用 async/await 关键字使该方法成为异步方法。

您可以使用 then() 和 catch() 方法使用该方法返回的 Promise。

示例

在下面的代码中,我们创建了 animal 类。

animal 类包含 getAnimalName() 方法并返回 ‘Lion’ 文本。我们在 ‘Lion’ 字符串之前使用了 await 关键字,它会暂停方法的执行,直到字符串创建完成。但是,您也可以返回 Promise。

之后,我们使用 then() 方法使用 Promise 并将动物名称打印到输出中。

<html>
<body>
   <div id = "output"> </div>
   <script>
      class animal {
         async getAnimalName() {
            return await "Lion";
         }
      }
      const lionObj = new animal();
      lionObj.getAnimalName().then((data) => {
         document.getElementById('output').innerHTML = "The animal name is: " + data;
      })
   </script>
</body>
</html>

输出

The animal name is: Lion

JavaScript Async/Await 的实时示例

以上示例是演示 JavaScript 中 async/await 关键字用法的基本示例。

让我们了解如何在实时开发中使用 async/await。

示例

在下面的代码中,当用户点击按钮时,它会调用 getData() 函数。

getData() 函数是一个异步函数。我们在函数内部使用了 try…catch 块来处理错误。

在 ‘try’ 块中,我们使用 fetch() API 从 API 获取数据并使用 ‘await’ 关键字。

之后,我们使用 response 的 json() 方法将其转换为 JSON 并使用该方法的 ‘await’ 关键字。

接下来,我们打印数据。

此外,我们在 catch() 方法中打印错误消息。

<html>
<body>
   <button onclick = "getData()">Get Data</button>
   <div id = "demo"> </div>
   <script>
      let output = document.getElementById('demo');
      async function getData() {
         try {
            let response = await fetch('https://api.github.com/users'); 
            // Pauses the execution until it gets the data
            let data = await response.json(); 
            // Pauses the execution until it converts the data into json
            output.innerHTML += "login: " + data[0].login + "<br>";
            output.innerHTML += "id: " + data[0].id + "<br>";
            output.innerHTML += "node_id: " + data[0].node_id + "<br>";
            output.innerHTML += "avatar_url: " + data[0].avatar_url + "<br>";
         } catch (err) {
            output.innerHTML += "The error is: " + json.stringify(err);
         }
      }
   </script>
</body>
</html>

输出

Real-time Example of JavaScript Async/Await

使用 JavaScript Async 函数的好处

以下是使用异步函数的一些好处。

  • 它提高了代码的可读性。
  • 它降低了代码的复杂性。
  • 它可以轻松地处理多个 Promise。
  • 它使调试更容易。
  • 您可以用异步函数替换回调函数和 Promise。
广告