Home > Web Front-end > JS Tutorial > body text

Explore the power of async and wait in JavaScript

WBOY
Release: 2023-08-31 15:33:10
Original
639 people have browsed it

探索 JavaScript 中 async 和 wait 的威力

In my previous tutorial, we covered the basics of Promises in JavaScript. I said at the end of the article that promises allow us to run our code asynchronously.

In this tutorial, we will learn about the async and await keywords in JavaScript, which allow us to use Promises effectively and write cleaner asynchronous code.

Definition async Function

Let’s start with asynchronous functions. Consider the following greeting function:

function greet() {
  return "Hello, World!";
}

// Outputs: Hello, World!
console.log(greet());
Copy after login

This is just a regular JavaScript function we've seen before. All it does is return a string that says "Hello, World!" However, we can turn this into an asynchronous function by just adding async in front of it, like this:

async function greet() {
  return "Hello, World!";
}

// Outputs: Promise { <state>: "fulfilled", <value>: "Hello, World!" }
console.log(greet());
Copy after login

This time, the function returns a Promise object with its state property set to Completed and its value set to Hello, World! In other words, the promise was resolved successfully.

We still return the string "Hello, World!" in the function definition. However, using the async keyword means that the return value will be wrapped in a resolved Promise object. The value of the resolved Promise will be the same as the value we returned from the async function.

You can also return your own promise from an async function like this:

async function greet() {
  return Promise.resolve("Hello, World!");
}

// Outputs: Hello, World!
greet().then((value) => console.log(value));
Copy after login

Basically, the async keyword helps us define a function that always returns a promise. You can explicitly return a Promise yourself, or have the function wrap any return value that is not a Promise into a Promise.

await Keywords

Any async function can contain zero or more await expressions. It is important to remember that the await keyword is only valid inside an async function. The await keyword is used to wait for a Promise to resolve or be rejected, and then get the completed value.

We use the await keyword, the syntax is as follows:

await expression
Copy after login

The expression can be a native Promise, in which case it is used directly and natively waited. In this case, there will be no implicit call to then(). The expression can be a thenable object, in which case a new Promise will be constructed by calling the then() method. The expression can also be a non-thenable value. In this case, an already implemented Promise will be constructed for us to use.

Suppose a promise has been fulfilled. async The execution of the function will still be suspended until the next tick. It's important to remember this.

The following is an example of using the await keyword in an async function:

async function greet() {
  let greeting = await "Hello, World!";
  return greeting;
}

// Outputs: [Function: Promise]
console.log(greet().constructor);

// Outputs: Hello, World!
greet().then((msg) => console.log(msg));
Copy after login

Here is another example of using the await keyword with an async function when using Promise explicitly:

async function greet() {
  let greeting = new Promise((resolve) => {
    setTimeout(() => {
      resolve("Hello, World!");
    }, 2000);
  });
  
  return greeting;
}

// Outputs: [Function: Promise]
console.log(greet().constructor);

// Outputs: Hello, World!
greet().then((msg) => console.log(msg));
Copy after login

This time, we explicitly use a Promise that resolves in 2 seconds. Therefore, the "Hello, World" greeting will be printed after two seconds.

Understand the execution order of statements

We will now write two different greeting functions and see the order in which they output their results.

function n_greet(person) {
  return `Hello, ${person}!`;
}

async function a_greet(person) {
  let greeting = await `Hello, ${person}!`;
  return greeting;
}
Copy after login

Our first function n_greet() is a normal function that returns a string as output. Our second function is the async function, which uses an expression after the await keyword. The return value in this case is a fulfilled promise.

Here is the code snippet that calls all these functions and logs the output:

a_greet("Andrew").then((msg) => console.log(msg));
console.log(n_greet("Adam"));

/* Output in order:
Hello, Adam!
Hello, Andrew! */
Copy after login

Greetings from Adam n_greet() The function call has ended. However, he was first welcomed in output. This is because the function call returns a string directly.

a_greet() The function call that greets Andrew at the beginning leads to the construction of a promise that has been fulfilled. However, execution remains suspended until the next clock cycle. That's why the output greeting appears after the greeting to Adam.

Now, we will define a slightly more complex async function that contains multiple statements. One of these statements will have the await keyword. You will see that using the await keyword in an async function pauses the execution of other statements following the await statement.

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))    
}

async function aa_greet(person) {
  console.log("Before Await..."); 
  await timeout(2000);
  let greeting = `Hello, ${person}!`;
  console.log("After Await...");
  
  return greeting;
}

Copy after login

Our async function contains an explicitly defined Promise, preceded by the await keyword. This means that the await keyword will wait for the Promise to be fulfilled and then return the fulfilled value. The promise will take 2 seconds to materialize, so after about 2 seconds we should see "After Await..." in the console log.

This is a code snippet that will record some statements of our async function:

console.log("Before Greeting Function...");
aa_greet("Monty").then((msg) => console.log(msg));
console.log("After Greeting Function...");

/* Output in Order
23:42:15.327 Before Greeting Function...
23:42:15.331 Before Await...
23:42:15.331 After Greeting Function...
23:42:17.333 After Await...
23:42:17.333 Hello, Monty! */
Copy after login

首先记录字符串“Before Greeting Function...”,因为这是我们进行的第一次调用。之后,我们调用 aa_greet() 函数。这会导致输出字符串“Before Await...”。然后,浏览器遇到 await 关键字。所以它等待承诺解决。与此同时,aa_greet()函数之外的代码继续执行。这就是为什么我们在下一个日志条目中得到“After Greeting Function...”字符串作为输出。

一旦承诺得到解决,浏览器就会继续执行,我们会得到“After Await...”作为输出。最后,我们解析的问候语作为承诺返回,因为我们使用 async 函数。我们对这个已解决的 Promise 调用 then() 方法并记录“Hello, Monty!”到控制台。

通过 Fetch API 使用 asyncawait

await 关键字的一个常见用例是从远程 API 获取数据。这允许比嵌套回调或承诺链更干净的代码。

async function getData() {
    // use the fetch API to fetch data from an API endpoint
    const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
    
    // check if the response is okay (HTTP status code 200-299)
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    
    // parse the response as JSON
    const data = await response.json();
    
    return data;
}
Copy after login

在此函数中,首先我们等待对 API 查询的初始响应。如果响应正常,我们就会等待 JSON 格式的完整响应数据。我们返回 JSON 数据,但请记住,由于这是一个异步函数,因此我们实际上返回一个最终解析为该数据的 Promise。因此,如果您想访问结果数据,您必须再次使用类似await关键字的东西!

const data = await getData();
Copy after login

最终想法

在上一篇教程中了解了 Promise 对象后,我们在本教程中讨论了 async 函数和 await 关键字。您现在应该能够编写自己的 async 函数,使用 await 关键字来使用更清晰、更易读的代码实现基于 Promise 的行为。

The above is the detailed content of Explore the power of async and wait in JavaScript. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template