This is the 17th day of my participation in the August Text Challenge.More challenges in August

preface

I have previously shared promise.then () is a good way to solve callback hell. In this article I have shared async and await, which uses promises but reduces Promise then processing and makes asynchronous request code much cleaner.

Async and await are ES7 grammars, which are syntactic candy based on Promise, making asynchronous code easier to write and read. By using them, asynchronous code looks more like old-fashioned synchronous code.

Async keyword

This is used to declare a function to be asynchronous. If the function returns a value, it guarantees that the return value will be a promise, rather than a direct return value.

let hello = async() = > {return "Hello" };
hello().then((value) = > console.log(value)) //Hello
Copy the code

If async returns a promise, then is also used to handle callbacks.

It’s ok to say ‘then’ but we have better ‘await’.

The await keyword

Await only works within asynchronous functions and can precede any asynchronous, promise-based function. It pauses the code on that line until the promise completes, then returns the result value. At the same time as the pause, other code waiting to be executed has a chance to execute.

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

Let’s compare code that uses promise. Then with code that uses async/await:

By default, fetch is an asynchronous function that returns a promise

Promise. Then:

fetch('coffee.jpg')
.then(response= > response.blob())
.then(myBlob= > {
  let objectURL = URL.createObjectURL(myBlob);
  let image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
})
.catch(e= > {
  console.log('There has been a problem with your fetch operation: ' + e.message);
});
Copy the code

Async/await:

async function myFetch() {
  let response = await fetch('coffee.jpg');
  let myBlob = await response.blob();

  let objectURL = URL.createObjectURL(myBlob);
  let image = document.createElement('img');
  image.src = objectURL;
  document.body.appendChild(image);
}

myFetch()
.catch(e= > {
  console.log('There has been a problem with your fetch operation: ' + e.message);
});
Copy the code

We can intuitively see that the latter removes.then() blocks everywhere, making the code more elegant and concise

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, as if a synchronization operation had been performed. It does allow other tasks to continue running in the meantime, but your own code is blocked.

This means that your code may be slow due to 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. Let’s look at some examples to prove this concept.

Call a fake asynchronous process with setTimeout() :

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

Each then contains a timeTest() asynchronous function waiting for three timeoutPromise() calls

async function timeTest() {
  await timeoutPromise(3000);
  await timeoutPromise(3000);
  await timeoutPromise(3000);
}
Copy the code

Here, we simply wait for all three timeoutPromise () calls, making each call 3 seconds. Each subsequent one is forced to wait until the last one is completed – if you run the first example, you’ll see pop-ups reporting a total running time of about 9 seconds.

async function timeTest() {
  const timeoutPromise1 = timeoutPromise(3000);
  const timeoutPromise2 = timeoutPromise(3000);
  const timeoutPromise3 = timeoutPromise(3000);

  await timeoutPromise1;
  await timeoutPromise2;
  await timeoutPromise3;
}
Copy the code

Here, we store the three Promise objects in variables that can start their associated processes at the same time.

Next, we wait for their results – since promises are all started at roughly the same time, promises will be fulfilled at the same time; When you run the second example, you’ll see pop-ups reporting a total elapsed time of just over 3 seconds!

conclusion

Async /await provides a nice, simplified way to write asynchronous code that is easier to read and maintain, since await blocks subsequent code you must carefully test your code and keep this in mind when performance starts to suffer.