Promise和await中的异步操作

Promise中的异步操作:

  • 基于then传递的 onfulfilled/onrejected 方法的执行是异步的
    • 哪怕执行 then 的时候,已经知道实例的状态和值了,也不会把 onfulfilled/onrejected 立即执行
    • 把其加入到 WebAPI 中监听「只不过已经确定了实例的状态,对应的方法是可以执行的」
    • 紧接着把其放到 EventQueue 的异步微任务队列中 排队等待执行!!
    • 等待同步代码执行完毕,主线程空闲下来了,把异步任务队列中的方法拿出来依次执行…

所以本质上,Promise中真正的异步操作是其原型上的then方法

由此可改进我们自己写的Promise源码中的then方法部分,因为我们的方法是基于兼容IE写的,所以采用的方法的用定时器不设时间或设置时间为0处理then方法中的代码(以及Promise源码中处理then传递的存起来的回调函数集合的执行),ES6中新增了一种方法用来创建一个异步的微任务:
queueMicrotask(() => {// 创建一个异步的微任务})

  • await 中的异步操作
    • 遇到 await ,立即把其下面的代码(当前上下文)放到 WebAPI 中监听「异步的微任务」
    • 再看 await 后面的实例是成功还是失败,如果是成功(可能要等一段时间),则说明此 微任务 可以执行,再把其放到 EventQueue 排队等待执行
    • 最后也是同步的都处理完毕了,才会把异步的拿过来处理

举个栗子

executor 函数的执行是同步的
  1. let p1 = new Promise((resolve) => {
  2. // executor 函数的执行是同步的
  3. console.log(1)
  4. resolve(100) // 修改实例的状态和值是同步的
  5. console.log(2)
  6. })
  7. console.log(3, p1)
  8. //==>1 2 3

使用到then才是异步
  1. let p1 = new Promise(resolve => {
  2. resolve(100)
  3. })
  4. p1.then(value => {
  5. console.log('成功:', value) //再输出'成功: 100'
  6. })
  7. console.log('OK') //先输出'OK'
  1. let p1 = new Promise(resolve => {
  2. setTimeout(() => {
  3. console.log(1) //@1
  4. resolve(100) //立即把实例的状态改为成功,值是100;通知集合中的方法执行的时候,不是让其立即执行,而是异步通知执行!!
  5. console.log(2) //@2
  6. }, 2000)
  7. })
  8. p1.then(value => {
  9. console.log('成功:', value) //@3
  10. })
  1. const fn = async () => {
  2. console.log(1) //@1
  3. await Promise.resolve(0)
  4. console.log(2) //@3
  5. }
  6. fn()
  7. console.log(3) //@2
  8. //执行到await时 其同一上下文中 下面的代码会以微任务形式存在WebAPI中,因为是立即知道状态为成功状态,所以直接放入EventQueue的异步微任务队列中等待同步任务执行结束,浏览器空闲下来后去队列中找到这个任务并执行

`LR043{V}L1]NBKFHLZJ]FW.jpg

练习题

第一个
  1. async function async1() {
  2. console.log('async1 start')
  3. await async2()
  4. console.log('async1 end')
  5. }
  6. async function async2() {
  7. console.log('async2')
  8. }
  9. console.log('script start')
  10. setTimeout(function () {
  11. console.log('setTimeout')
  12. }, 0)
  13. async1()
  14. new Promise(function (resolve) {
  15. console.log('promise1')
  16. resolve()
  17. }).then(function () {
  18. console.log('promise2')
  19. })
  20. console.log('script end')

ARY9G5Z]U9I(1RFC%Y6DAVR.jpg

第二个
  1. let body = document.body//记得给body和html同时设置宽高 不然点不到
  2. body.addEventListener('click', function () {
  3. Promise.resolve().then(() => {
  4. console.log(1)
  5. })
  6. console.log(2)
  7. })
  8. body.addEventListener('click', function () {
  9. Promise.resolve().then(() => {
  10. console.log(3)
  11. })
  12. console.log(4)
  13. })

![BIME8LD27)6OH3RU24AK_X_tmb.jpg