【js】事件循环之promise的async/await与setTimeout

什么是事件循环

事件循环又叫消息循环,是浏览器渲染主线程的工作方式。

浏览器开启一个永不停止的for循环,每次循环都会从消息队列中取任务,其他线程只需要在合适的时候将任务加入到消息队列的末尾。

过去分为宏任务和微任务,现在由于浏览器环境越来越复杂,宏任务的说法已经不合适,取而代之的是w3c官网新提出的,每个任务都会带有任务类型,同类型的任务放在同对列,不同的任务可以放在不同的对列,不同的对列有不同的优先级,(任务没有优先级)由浏览器自行决定优先执行哪一个,但是总会有一个微队列,优先级最高

在这里插入图片描述

什么是async与await

async/await是JavaScript中处理异步操作的一种方式,它是基于Promise的语法糖。

async关键字用于声明一个函数是异步的,而await关键字用于等待一个Promise解析完成。

此时可以认为,在await之后的代码其实是promise完成之后才执行,也就是说相当于promise.then回调执行的的内容,只是通过async / await语法糖解决了promise的回调嵌套问题

事件循环中的同步任务与异步任务

众所周知,同步任务即按顺序执行,异步任务即开启新线程与主线程并行执行

常见的异步任务有 promise、setTimeout、nextTick等,而这些在之前又分为宏任务和微任务,但其实现在官方更改了宏任务的说法,提出分类型的任务队列(后面统称为其他异步队列)和微队列,微队列的优先级高于其他异步队列。promise.then和nextTick属于微任务,会进入微队列
在这里插入图片描述

在事件循环过程中,按顺序处理当前消息队列中的任务; 当遇到await关键字时,JavaScript会将该异步函数暂停(也就是指暂停当前 async function 内部await之后的代码执行)

其实此时await后面的代码产生一个微任务,进入微队列,浏览器主线程将其放入微队列后将继续执行消息队列中的任务,直到消息队列中的任务全部执行完成之后,微队列的任务才会进入到消息队列去执行

需要注意的是,虽然await会暂停代码执行,但它不会阻塞事件循环。这意味着其他任务(已在消息队列中的后面的任务)可以在等待Promise解析期间继续执行。

案例

async function async1 () {
  console.log(1)
  await async2()
  console.log(2)
}

async function async2 () {
  console.log(3)
}

console.log(4)

setTimeout(function () {
  console.log(5)
}, 0)

async1()

new Promise(function (resolve) {
  console.log(6)
  resolve()
}).then(function () {
  console.log(7)
})

console.log(8)

// 4 1 3 6 8 2 7 5

解析

首先解析这些js代码,将任务按照代码执行顺序放入消息队列,初始队列如下图
在这里插入图片描述

开始执行之后

1、首先控制台输出4
2、其次执行setTimeout,为异步任务,并且不是微任务,放入其他异步队列,交给其他线程进行处理
3、执行到async1(),进入async1()函数内部执行

async function async1 () {
  console.log(1)
  await async2()
  console.log(2)
}

进入async1()函数内部开始执行

1、控制台输出1
2、进入async2()执行并等待,也就是将await async2()后面的内容console.log(2)放入微队列等待promise解析完成后放入消息队列。而async2()内部只有console.log(3),是同步任务,立即执行,控制台输出3。此时的消息队列图如下
在这里插入图片描述

继续执行,进入new Promise()

1、控制台输出6
2、.then()放入微队列
3、继续执行控制台输出8,此时的消息队列图如下

在这里插入图片描述

消息队列清空后,微队列的任务进入消息队列,继续执行

1、控制台输出2
2、执行then函数,输出7
3、微队列任务清空,其他异步队列任务进入消息队列开始执行
在这里插入图片描述

控制台输出5,至此所有任务执行完毕,控制台输出 4 1 3 6 8 2 7 5
在这里插入图片描述

  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麻辣翅尖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值