preface

Asynchronous operation has always been an indispensable part of JS. From the callback function at the beginning, to the Promise, and then to the async function introduced in ES2017, asynchronous operation has gradually evolved and become more and more simple and convenient. Next, we will take a closer look at the changes generated by asynchronous operation after the introduction of async function in ES2017.

What’s the use of

We used to use async/await functions together, but this time I’m going to break it down and introduce async and await respectively

Async role

Normally async is used because there is an await command inside a function, because an await command can only appear inside an async function, otherwise the syntax will be declared, that is why async/await is used in pairs, but what happens if an async is added to a normal function separately? Here’s an example:

async function test () {
  let a = 2
  return a
}
const res = test()
console.log(res)
Copy the code

res.then(a= > {
  console.log(a) / / 2
})
Copy the code

In the absence of await, calling async will execute immediately and return a Promise, what difference will it make with await?

Await role

Normally, an await command is followed by a Promise and waits for the state of the Promise to change and get the return value, but it can also be followed by the return result of any expression. For example:

function a () {
  return 'a'
}
async function b () {
  return 'b'
}
const c = await a()
const d = await b()
console.log(c, d) // 'a' 'b'
Copy the code

In this example, we can see that no matter what expression is followed by await, we can wait for the result to return. When await is not a Promise object, we will return the result. When await is a Promise object, we will block the following code, waiting for the state of the Promise object to change. Get the corresponding value as the result of await, the block here refers to the block inside async, the call of async function will not block

What problem was solved

Promise… Why use async/await when the then syntax has solved the problem of nested layers of callbacks that always existed before? To answer this question, take a look at the Promise code:

function login () {
  return new Promise(resolve= > {
    resolve('aaaa')})}function getUserInfo (token) {
  return new Promise(resolve= > {
    if (token) {
      resolve({
        isVip: true})}})}function getVipGoods (userInfo) {
  return new Promise(resolve= > {
    if (userInfo.isVip) {
      resolve({
        id: 'xxx'.price: 'xxx'})}})}function showVipGoods (vipGoods) {
  console.log(vipGoods.id + The '-' + vipGoods.price)
}
login()
  .then(token= > getUserInfo(token))
  .then(userInfo= > getVipGoods(userInfo))
  .then(vipGoods= > showVipGoods(vipGoods))
Copy the code

As shown in the example, each Promise is equivalent to an asynchronous network request. Usually a business process requires multiple network requests, and network requests depend on the result of one request. In the example above, Promise simulates this process.

async function call() {
  const token = await login()
  const userInfo = await getUserInfo(token)
  const vipGoods = await getVipGoods(userInfo)
  showVipGoods(vipGoods)
}
call()
Copy the code

The async/await call is much cleaner and simpler than the Promise then chain call, as is the synchronous code

What are the problems

When using async/await, we often ignore a problem that the accumulated time brought by synchronous execution will cause the program to slow down. Sometimes our code can be written as concurrent execution, but since async/await is made as secondary execution, let’s take an example:

function test () {
  return new Promise(resolve= > {
    setTimeout((a)= > {
      console.log('test')
      resolve()
    }, 1000)})}function test1 () {
  return new Promise(resolve= > {
    setTimeout((a)= > {
      console.log('test1')
      resolve()
    }, 1000)})}function test2 () {
  return new Promise(resolve= > {
    setTimeout((a)= > {
      console.log('test2')
      resolve()
    }, 1000)})}async function call () {
  await test()
  await test1()
  await test2()
}
call ()
Copy the code

The following code takes time to execute:

function call () {
  Promise.all([test(), test1(), test2()])
}
call()
Copy the code

Time spent:

Small problems in the loop

ForEach is one of the many useful array apis that you can use to write javascript loops. ForEach is an async/await object.

function getUserInfo (id) {
  return new Promise(resolve= > {
    setTimeout((a)= > {
      resolve({
        id: id,
        name: 'xxx'.age: 'xxx'})},200)})}const users = [{id: 1}, {id: 2}, {id: 3}]
let userInfos = []
users.forEach(async user => {
  let info = await getUserInfo(user.id)
  userInfos.push(info)
})
console.log(userInfos) / / []
Copy the code

The forEach loop is async/await. The forEach loop is async/await. The forEach loop is async/await. So instead of waiting for all user information to be requested before printing userInfos, instead of waiting for the result to return, go back to the old fashioned for loop and look at the code:

function getUserInfo (id) {
  return new Promise(resolve= > {
    setTimeout((a)= > {
      resolve({
        id: id,
        name: 'xxx'.age: 'xxx'})},200)})}const users = [{id: 1}, {id: 2}, {id: 3}]
let userInfos = []
async function call() {
  for (user of users) {
    let info = await getUserInfo(user.id)
    userInfos.push(info)
  }
  console.log(userInfos)
}
call()
Copy the code

function getUserInfo (id) {
  return new Promise(resolve= > {
    setTimeout((a)= > {
      resolve({
        id: id,
        name: 'xxx'.age: 'xxx'})},200)})}const users = [{id: 1}, {id: 2}, {id: 3}]
let userInfos = []
const promises = users.map(user= > getUserInfo(user.id))
Promise.all(promises).then(res= > {
  userInfos = res
  console.log(userInfos)
})
Copy the code

conclusion

This article has made a simple summary of the usage of async/await and some problems frequently encountered. I hope it can be helpful for you to use it. If there is a mistake or not rigorous place, welcome criticism and correction, if you like, welcome to praise