事件循环:执行栈、Web API 、 执行队列 之间的循环过程(异步)

事件循环


前提

了解三个部分:

  • 执行栈:JS代码只会在执行栈执行,不可能在其他地方执行
  • Web API : 浏览器的其他线程(计时、事件监听……)
  • 事件队列



举例

下列代码的输出结果是?

const a = 1;
console.log(a);

function A() {
  console.log('A');
  B();
}

function B() {
  console.log('B');
}

A();

答:
3
4
1
3
2
2




过程解析

图一:初始状态

  • JS启动之前就会分配一块内存空间(执行引擎干的事),就是执行栈call stack
  • JS执行引擎会往执行栈内放入一块全局上下文

在这里插入图片描述


图二:代码从上往下执行

  • 第一条:是setTimeout计时的回调函数,执行栈通知浏览器的计时线程开始计时(时间为0秒,计时完成后需要执行的函数是fn)
  • 发送通知完成后,setTimeout执行完成,出栈
  • 计时结束后(计时线程根据规定的计时器时间来定,与执行栈没有关系),有需要执行的函数,则到执行队列中排队,等待执行栈休息时(空闲时),便会从执行队列中,按顺序执行(同时计时线程完毕)

在这里插入图片描述



图三:setTimeout一条语句执行完后的的结果:回到全局上下文

在这里插入图片描述



图四:代码继续从上往下执行

  • 函数声明不用理会
  • 第二条语句执行:a();
 a();
  • 形成函数a的上下文,函数a上下文入栈,函数a里面继续执行,执行setTimeout的回调函数
  • 执行栈通知浏览器的计时线程开始计时(时间为0秒,计时完成后需要执行的函数是fn2)
  • 发送通知完成后,setTimeout执行完成,出栈
  • 计时结束后,有需要执行的函数,到执行队列中排队,等待执行栈休息时,便会从执行队列中,按顺序执行(同时计时线程完毕)

在这里插入图片描述



图五:继续执行函数a里的语句

  • 执行log语句,产生log上下文,则log上下文入栈

在这里插入图片描述



图六:输出3

  • log语句执行完毕,log上下文出栈

在这里插入图片描述



图七:函数a完毕执行完毕,函数a上下文执行完毕,出栈

在这里插入图片描述



图八:回到全局上下文,继续往下执行

  • 执行语句:
console.log(4);
  • 触发log上下文,入栈
    在这里插入图片描述



图九:执行完 log语句后,后输出4

  • log上下文出栈

在这里插入图片描述



图十:回到全局上下文,全局中所有语句执行完毕,则全局上下文出栈,执行栈空闲,可以休息

在这里插入图片描述



图十一:执行栈休息中

  • 执行栈休息时,会从执行队列中拿取需要执行的函数,进行执行
  • 从队列头开始拿,fn

在这里插入图片描述



图十二:执行栈准备执行函数fn,则触发fn上下文入栈,fn2自动补齐到队列头

在这里插入图片描述



图十三:执行函数fn,从上往下执行

  • fn函数内的第一条语句是:console.log(1),触发log上下文入栈

在这里插入图片描述



图十四:输出1,log执行完毕,log上下文执行完毕,出栈

在这里插入图片描述



图十五:执行函数fn,从上往下执行

  • fn函数内的第二条语句是:a(),触发函数a上下文入栈

在这里插入图片描述



图十六:函数a里面继续执行,执行setTimeout

  • 执行栈通知浏览器的计时线程开始计时(时间为0秒,计时完成后需要执行的函数是fn3),
  • 发送通知完成后,setTimeout执行完成,出栈
  • 计时结束后,有需要执行的函数,到执行队列中排队,等待执行栈休息时,便会从执行队列中,按顺序执行(同时计时线程完毕)

在这里插入图片描述



图十七:继续执行函数a内的语句:console.log(3);触发log上下文入栈

在这里插入图片描述



图十八:输出3,执行完log语句后,log上下文出栈

  • 函数a也执行完毕,函数a上下文也出栈
  • 自此:fn函数也执行完毕,fn上下文出栈

在这里插入图片描述



图十九:同上可得,fn上下文出栈后

  • 执行栈休息时,会又从执行队列中拿取队列头的fn2函数,进行行执行
  • fn2上下文入栈,执行fn2函数语句,console.log(2),触发log语句,log上下文入栈
  • 输入2后,log执行完毕,log上下文出栈

在这里插入图片描述



图二十:fn2函数执行完毕后,fn2上下文出栈

  • 执行栈空闲,继续从执行队列中拿取等待执行函数fn3,fn3上下文入栈

在这里插入图片描述



图二十一:执行完log语句,log上下文出栈

在这里插入图片描述



图二十二:函数fn3执行完毕,fn3上下文出栈

在这里插入图片描述



图二十三:执行栈空闲,执行队列也空闲,则执行栈休息

在这里插入图片描述




课堂作业

输出结果是?

setTimeout(() => {
  console.log(1);
}, 0);
const start = Date.now();
while (Date.now() - start < 1000) {}

console.log(2);

答:2 1

自主分析过程哟~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值