Let’s start with promise

The following code can be better understood using Promise

async function a(){
    console.log(1)
    const w = await v
    console.log(3)
    return w
}
a()
console.log(2)
Copy the code

Similar to the

A () : console.log(1) encounters await V, assuming v is notfunctionFinalPromise = promise.resolve (v).then((res)=>{console.log(3);returnRes}) if v is a promise finalPromise = v.chen ((res)=>{console.log(3);returnRes}) is then thrown to the thread that handles the promise:returnPromise.resolve(finalPromise) : console.log(2) The Promise is executed by another thread, and the resolve callback is added to the micro task stack, which is already behind the main thread:  console.log(3)return res
Copy the code

V is resolved and resumes in the current scope. Suspend delay is await. V is resolved and resumes in the current scope

Throw out problem

Every time when async and await are used, especially when forEach is used and there are multiple await, it is very confusing to execute which one should be performed first. I hope to make it clear.

To solve the problem

Reference: Faster Async functions and promises

First look at the v8 illustration:

The original code is on the left, and the interpreted code is on the right.

Next, as with math problems, first define several theorems:

theorem

1, promise. resolve(Promise) === Promise is true

This is based on the promiseResolve function shown belowCopy the code

Theorem 2. Async returns a promise

Because of the simplified diagram of function V8, there is no endreturnSo the implementation should not be quite consistent but this must be correct ha!! What should be returned is a resolvePromise(implICIT_promise, w) at the end of the function, something like thisreturn Promise.resolve(w)
Copy the code

Theorem 3, await v is similar to promise.resolve (v)

Resolve(v) will create a promise if v is a promise: According to theorem 1, the return is the promise of VCopy the code

Theorem 4. If function is followed by await, function will be performed first

When I see a function, I push it first, right?Copy the code

Theorem 5: The code after “await” is executed after the promise returned by “await” is resolved, which can be interpreted as “then”

The official issuspendResume, resume, put in this promisethenIf there is a problem with async, please correct itfunction a(){
    console.log(1)
    const w = await v
    console.log(3)
    returnW} According to theorem 2 and 3 are similar tofunction a(){
    console.log(1)
    return Promise.resolve(
        Promise.resolve(v).then((res)=>{console.log(3);returnRes}))} according to theorem 1 is equivalent tofunction a(){
    console.log(1)
    return Promise.resolve(v).then((res)=>{console.log(3);returnRes})} If v is a promise by the theorem 1 is equivalent tofunction a(){
    console.log(1)
    return v.then((res)=>{console.log(3);return res})
}
Copy the code

Easy edition

If we encounter await, any code execution beyond the current scope that is not function is wrapped up and thrown out to await asynchronous execution, and then the synchronous code continues to execute

Let me give you another example

const a=async (index)=>{
    console.log("a0"+index)
    await console.log("a1"+index)
    console.log("a2"+index)
}

async function example() {const nums = [2,2] nums.foreach (async (num,index) => {console.log('forEach${index}`)
    const b = await a(index)
    console.log(index)
  })
  console.log('out')
}

example()
console.log('example finished')
Copy the code

Similar to the

Example is pushed into the stack.forEach executes: console.log('forEach0') get await, awaitfunctionA () : console.log()"a00"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}"a10"), return undefined to await undefined, and then wrap up the code behind its scope and throw it away:return promiseA = Promise.resolve(undefined).then(()=>{console.log("a2"});});};returnPromiseB = promisea.then (()=>{console.log(b)}) is packed and thrown to wait for the first asynchronous executionforEach goes off the stack, and the second one goes on the stack (forEach is a synchronization process) : Repeat the steps above, assuming that the second one is eventually thrown as promiseCforCall console.log();'example finished'Main program complete, empty microservice stack: firstforIs the header of Each promise chain(promiseB) resolved first or the second (promiseC) header resolved first? Because everything on this side is immediately resolved and therefore promiseBthenCall B1, promiseCthenCallback C1 is queued to execute B1's console.log("a20"Return a resolve promise upon executionthenCall B2 to join the microservice queue and execute C1 console.log("a21"Return a resolve promise upon executionthenCallback C2 joins the end of the microservice queue to execute B2thenThe callback to console.log(0) performs C2'sthenThe console.log(1) callback resultsforEach0
a00
a10
forEach2
a01
a11
out
example finished
a20
a21
0
1
Copy the code