用promise理解async、await

栏目: JavaScript · 发布时间: 6年前

内容简介:以下代码可以用promise更好理解类似于注意:v8里面碰到await这一步说是suspend延迟,当v被resolve的时候会resume恢复到当前作用域那一步执行,我自己也不太懂里面的具体实现,这边这样理解如果有误希望指正

以下代码可以用promise更好理解

async function a(){
    console.log(1)
    const w = await v
    console.log(3)
    return w
}
a()
console.log(2)
复制代码

类似于

先入栈执行a():
    console.log(1)
遇到await v,假设v不是function,则后面都用promise包起来:
    假设v是一个基本类型
    finalPromise = Promise.resolve(v).then((res)=>{console.log(3);return res}) 
    若v是一个promise
    finalPromise = v.then((res)=>{console.log(3);return res})
然后扔出去给处理promise的线程执行:
    return Promise.resolve(finalPromise)
扔出去后函数a出栈,继续执行:
    console.log(2)
promise由其他线程执行,resolve后回调进入微任务堆栈,这已经是主线程之后的任务了:
    console.log(3)
    return res
复制代码

注意:v8里面碰到await这一步说是suspend延迟,当v被resolve的时候会resume恢复到当前作用域那一步执行,我自己也不太懂里面的具体实现,这边这样理解如果有误希望指正

抛出问题

每次在使用async和await的时候,尤其在使用forEach、有多个await的时候,对哪个先执行非常混乱,希望能够理清楚。

解决问题

reference: Faster async functions and promises

先看v8解释图:

用promise理解async、await

左边是原始代码,右边是解释后的代码。

接下来跟做数学题一样,首先定义几个定理:

定理

定理1、Promise.resolve(promise) === promise为真

这个是根据下面promiseResolve这个函数得出的,图在下面
复制代码
用promise理解async、await

定理2、async函数返回一个promise

由于函数v8的简易解释图最后没有return的操作,所以实现应该不太一致
但这一定是正确的哈!!!
返回的应该是函数最后的 resolvePromise(implicit_promise, w)
类似于 return Promise.resolve(w)
复制代码

定理3、await v 类似于 Promise.resolve(v)

根据v8图里面的: promise = promiseResolve(v) 
如果v不是一个promise:
    await v 类似于 Promise.resolve(v)会创建一个promise
如果v是一个promise:
    根据定理1,返会的就直接是v这个promise
复制代码

定理4、await后面是function的话是会先执行function的

遇到函数都会先入栈执行吧?
复制代码

定理5、await所在作用域的await后面的代码,其执行时间都是在这个await返回的promise被resolve后,可以理解成放在then里面

官方是suspend、resume这种实现的,理解成放在这个promise的then里面如果有问题希望及时指正
async function a(){
    console.log(1)
    const w = await v
    console.log(3)
    return w
}
根据定理2、3类似于
function a(){
    console.log(1)
    return Promise.resolve(
        Promise.resolve(v).then((res)=>{console.log(3);return res})
    )
}
根据定理1等价于
function a(){
    console.log(1)
    return Promise.resolve(v).then((res)=>{console.log(3);return res})
}
如果v是一个promise的话根据定理1等价于
function a(){
    console.log(1)
    return v.then((res)=>{console.log(3);return res})
}
复制代码

简易理解版

遇到await,当前作用域之后的代码执行如果不是function就都包起来扔出去等待异步执行,然后继续执行同步代码

再加一个例子

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')
复制代码

类似于

example进栈执行,forEach执行:
    console.log('forEach0')
遇到await,await后面是function,入栈执行a():
    console.log("a00")
又发现await且后面是函数,执行console.log:
    console.log("a10"),返回undefined
变成await undefined,于是将其作用域后面的代码打包起来扔出去:
    return promiseA = Promise.resolve(undefined).then(()=>{console.log("a2")})
    扔出去等待异步执行
a出栈,返回的是promiseA,在example中变成await promiseA:
    return promiseB = promiseA.then(()=>{console.log(b)})
    打包起来扔出去等待异步执行
第一个forEach函数出栈,第二个入栈(forEach是同步过程):
    重复上面几个步骤,假设最终是promiseC被扔出去 
第二个forEach函数出栈,example出栈:
    执行console.log('example finished')
主程序完成,清空微服务栈:
    第一个forEach的promise chain(promiseB)的头部还是第二个(promiseC)的头部先被resolve?
    因为这边的都是立即resolve的
    因此promiseB的then回调B1、promiseC的then回调C1先后被加入队列
    执行B1的console.log("a20")
    执行完返回一个被resolve的promise于是其then回调B2加入微服务队列尾部
    执行C1的console.log("a21")
    执行完返回一个被resolve的promise于是其then回调C2加入微服务队列尾部
    执行B2的then的回调的console.log(0)
    执行C2的then的回调的console.log(1)

最终结果
forEach0
a00
a10
forEach2
a01
a11
out
example finished
a20
a21
0
1
复制代码

以上所述就是小编给大家介绍的《用promise理解async、await》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Practical JavaScript, DOM Scripting and Ajax Projects

Practical JavaScript, DOM Scripting and Ajax Projects

Frank Zammetti / Apress / April 16, 2007 / $44.99

http://www.amazon.com/exec/obidos/tg/detail/-/1590598164/ Book Description Practical JavaScript, DOM, and Ajax Projects is ideal for web developers already experienced in JavaScript who want to ......一起来看看 《Practical JavaScript, DOM Scripting and Ajax Projects》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

html转js在线工具
html转js在线工具

html转js在线工具