I haven’t written my blog for a long time. Today, I finally finished writing an article that I had been dragging for a long time.

A Promise you must Know

1. You must know the Promise.

Async/await the foundation

Promises are cleaner than the unreadable nesting of callback functions, but promises can have long chains and nesting when there are many tasks, and using async/await makes the code much easier to read.

async

Async functions can be thought of as syntactic candy for promises:

/ / resolve state
async function foo() {
    console.log('start')
    return 'resolve'
}
foo().then(data= > {
    console.log('data:, data)
})
console.log('end')
// start
// end
/ / data: resolve


/ / reject status
async function foo() {
    console.log('start')
    throw new Error('reject')
}
foo().catch(data= > {
    console.log('data:, data.message)
})
console.log('end')
// start
// end
/ / data: reject
Copy the code

This is exactly what happens when you write it as a Promise:

/ / resolve state
function foo() {
    return new Promise((resolve, reject) = > {
        console.log('start')
        resolve('resolve')
    })
}
foo().then(data= > {
    console.log('data:, data)
})
console.log('end')
// start
// end
/ / data: resolve


/ / reject status
function foo() {
    return new Promise((resolve, reject) = > {
        console.log('start')
	reject('reject')
    })
}
foo().catch(data= > {
    console.log('data:, data)
})
console.log('end')
// start
// end
/ / data: reject
Copy the code

await

‘await’ means the same as’ await ‘- to wait for the subsequent function to complete.

/ / resolve state
async function foo() {
    console.log('start')
    return 'resolve'
}
async function bar() {
    const data = await foo()
    console.log('data', data)
}
bar()
console.log('end')
// start
// end
// data resolve

/ / reject status
async function foo() {
    console.log('start')
    throw new Error('reject')}async function bar() {
    try {
        const data = await foo()
        console.log('data', data)
    } catch (err) {
	console.log('data', err.message)
    }
}
bar()
console.log('end')
// start
// end
// data reject
Copy the code

Await can only be used in async functions, otherwise an error will be reported

Async /await in the loop

Consider the following two scenarios first:

  1. There is an asynchronous request that needs to be sent multiple times and in order

  2. There is an asynchronous request that needs to be sent multiple times, but not in order

The scene of a

Same request, multiple times, in order. This is a typical serial processing

function mockServer(i) {
    return new Promise((reslove, rejecy) = > {
        setTimeout((a)= > {
	    reslove('Worth it:' + i)
        }, 1000 * i)
    })
}

async function getData(time) {
    var data = await mockServer(time)
    return data
}

var arr = [1.2.3.4]

async function showData() {
  console.time('showData')

  for (const item of arr) {
    const data = await getData(item)
    console.log(data)
  }
  console.timeEnd('showData')
}
showData()

// It has a value of 1
// It has a value of 2
// The value is: 3
// It has a value of 4
/ / howData: 13100.510009765625 ms
Copy the code

We called the asynchronous function getData for 4 times through the for-of loop. As getData was preceded with the keyword await, it was queued up and processed successively. It took more than 13 seconds in total.

Scenario 2

Same request, multiple times, out of order. This is a typical parallel processing, where each request is sent at the same time instead of waiting in a queue, saving time.

function mockServer(i) {
    return new Promise((reslove, rejecy) = > {
        setTimeout((a)= > {
	    reslove('Worth it:', i)
        }, 1000 * i)
    })
}

async function getData(time) {
    var data = await mockServer(time)
    return data
}

var arr = [1.2.3.4]

async function showData() {
  console.time('showData')

  var allAsyncRequest = arr.map(item= > getData(item))
  for await  (const asyncRequest of allAsyncRequest) {
    const data = asyncRequest
    console.log(data)
  }
  console.timeEnd('showData')
}
showData()

// It has a value of 1
// It has a value of 2
// The value is: 3
// It has a value of 4
/ / showData: 4131.318115234375 ms
Copy the code

We called the map callback four times, placing the request event in the event queue so that all four requests could be processed at the same time without affecting the execution of subsequent tasks.

Then pass for await… Of waits for all four asynchronous requests to complete, which takes a total of four seconds, saving a lot of time.

Here for await… Of can also be written in another way:

for (const asyncRequest of allAsyncRequest) {
    const data = await asyncRequest
    console.log(data)
}
Copy the code

Promise.all() can also be used:

Promise.all(allAsyncRequest).then((data) = > {
    console.log(data)
    console.timeEnd('showData')})// [" value: 1", "value: 2"," value: 3", "value: 4"]
/ / showData: 4441.679931640625 ms
Copy the code

Note: forEach cannot be used for loop processing, for reasons that are clear in this article when async/await is encountered with forEach.

The last

Learn to skillfully use async/await to make your code readable and maintainable. If you have better usage and suggestions, please add them in the comments section.