Async keyword

  1. Normal function call, return “Hello”
function hello() { return "Hello" };
hello(); //"Hello"
Copy the code
  1. Declare an async call and return a Promise
async function hello() { return "Hello" };
hello(); //Promise {<resolved>: "Hello"}
Copy the code

Here’s the equivalent:

// Create an asynchronous function expressionlet hello = async function() { return "Hello"}; hello(); // Use the arrow functionlet hello = async () => { return "Hello" };
hello();
Copy the code
  1. Since a promise is returned, we can use the.then() block
hello().then((value) => console.log(value)); //Hello // Short Hello ().then(console.log); //HelloCopy the code

The await keyword

You can use await when calling any function that returns a Promise, including Web API functions.

The await keyword causes the JavaScript runtime to pause the code on this line, allowing other code to execute in the meantime until the asynchronous function call returns its result. Once complete, your code continues to execute from the next line.

async function hello() {
  return greeting = await Promise.resolve("Hello");
};

hello().then(alert); //Hello
Copy the code
  1. Can’t use await in regular functions
function f() {
  let promise = Promise.resolve(1);
  let result = await promise; //Uncaught SyntaxError: await is only valid in async function
}
Copy the code
  1. Await won’t work in the top-level code
<! DOCTYPE html> <html lang="en">
  <body>
  </body>
  <script>
  'use strict';
  // syntax error in top-level code
  let response = await fetch('https://cnodejs.org/api/v1/topics');
  let user = await response.json();
  console.log(user);
  </script>
</html>
Copy the code

we can wrap it into an anonymous async function

<script>
  'use strict';
  // syntax error in top-level code
  (async () => {
    let response = await fetch('https://cnodejs.org/api/v1/topics');
    letuser = await response.json(); alert(user); }) (); </script>Copy the code
  1. Await accepts “thenables”
class Thenable {
  constructor(num) {
    this.num = num;
  }
  then(resolve, reject) {
    // resolve with this.num*2 after 1000ms
    setTimeout(() => resolve(this.num * 2), 1000); / / (*)}}; asyncfunction f() {
  // waits for 1 second, then result becomes 2
  let result = await new Thenable(1);
  console.log(result);
}

f();
Copy the code
  1. Class method

We can add async before class/object methods to make them return Promises and await promises inside them.

class Person {
  constructor(name) {
    this.name = name;
  }

  async greeting() {
    return await Promise.resolve(`Hi! I'm ${this.name}.`); }; } let jim = new Person('Jim');
jim.greeting().then(console.log); //Hi! I'm Jim.
Copy the code

Rewrite the Promise code with async/await

  1. Promise to realize
fetch('https://cnodejs.org/api/v1/topics')
.then(response => response.json())
.then(data => {
  console.log(data);
})
.catch(e => {
  console.log('There has been a problem with your fetch operation: ' + e.message);
});
Copy the code
  1. Use async/await implementation
async function myFetch() {
  let response = await fetch('https://cnodejs.org/api/v1/topics');
  let data = await response.json();
  console.log(data);
}

myFetch()
.catch(e => {
  console.log('There has been a problem with your fetch operation: ' + e.message);
});
Copy the code
  1. Refactor the code
async function myFetch() {
  let response = await fetch('https://cnodejs.org/api/v1/topics');
  return await response.json();
}

myFetch().then((data) => {
  console.log(data);
})
Copy the code

Add error handling

async function myFetch() {
  try {
    let response = await fetch('https://cnodejs.org/api/v1/topics');
    let data = await response.json();
    console.log(data);
  } catch(e) {
    console.log(e);
  }
}

myFetch();
Copy the code
async function myFetch() {
  let response = await fetch('https://cnodejs.org/api/v1/topics');
  return await response.json();
}

myFetch().then((data) => {
  console.log(data);
})
.catch((e) =>
  console.log(e)
);
Copy the code

Wait for the Promise. All ()

Async /await is built on Promises, so it is compatible with everything Promises offers.

async function myFetch(url) {
  const response = await fetch(url);
  return await response.json();
}

async function init() {
  let topicList = myFetch('https://cnodejs.org/api/v1/topics');
  let topicItem = myFetch('https://cnodejs.org/api/v1/topic/5e4fa8531225c9423dcda9d8');
  let userInfo = myFetch('https://cnodejs.org/api/v1/user/lellansin');

  let values = await Promise.all([topicList, topicItem, userInfo]);
  console.log(values);
}
Copy the code

The defects of async/await

Async /await makes your code look synchronous and, in a way, makes it behave more synchronous. The await keyword blocks subsequent code until the promise completes.

The code may get slow because of lots of await promises happening one after another. Each await will wait for the previous one to finish, and what you really want is for all promises to start processing at the same time (just like when we are not using async/await).

One pattern alleviates this problem — start Promise objects simultaneously by storing them in variables, and then wait for them all to complete.

function timeoutPromise(interval) {
  return new Promise((resolve, reject) => {
    setTimeout(function(){
      resolve("done");
    }, interval);
  });
};

async function timeTestSlow() {
  await timeoutPromise(3000);
  await timeoutPromise(3000);
  await timeoutPromise(3000);
}

let startTime = Date.now();
timeTestSlow().then(() => {
  let finishTime = Date.now();
  let timeTaken = finishTime - startTime;
  console.log("Time taken in milliseconds: " + timeTaken); //Time taken in milliseconds: 9013
})
Copy the code

Another way to write it

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

async function timeTestSlow() {
  await timeout(3000);
  await timeout(3000);
  await timeout(3000);
}

function doit(){
  console.time("doit");
  timeTestSlow().then(() => {
    console.timeEnd("doit"); }) } doit(); / / doit: 9008.90380859375 msCopy the code

Save it in variables

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

async function timeTestFast() {
  const timeout1 = timeout(3000);
  const timeout2 = timeout(3000);
  const timeout3 = timeout(3000);

  await timeout1;
  await timeout2;
  await timeout3;
}

function doit(){
  console.time("doit");
  timeTestFast().then(() => {
    console.timeEnd("doit"); }) } doit(); / / doit: 3002.612060546875 msCopy the code

More

Making Asynchronous programming Easier with async and await developer.mozilla.org/en-US/docs/…

Async and await: Making asynchronous programming easier developer.mozilla.org/zh-CN/docs/…

Understand the async/await JavaScript segmentfault.com/a/119000000…

The meaning and usage of the async function www.ruanyifeng.com/blog/2015/0…

Async/Await: six reasons caibaojian.com/asyncawait. better than Promise…