js的事件循环机制

js的事件循环机制,也就是俗称的EventLoop?其实也是非常的普通,不要被🐯到。

1. 首先因为js被用来操作页面dom,当操作dom的时候增删改是一定不能多线程去操作的(否则会带来很多复杂的问题),这也就限制了js是一门单线程语言,然而单线程语言要实现一些类似于多线程的功能就衍生出了异步的概念。

2.在es5之前js的事件循环机制也就是分为简单的同步执行和异方式步执行的方式,当遇到同步代码的时候就直接交给调用栈执行,当遇到异步代码的时候就交给宿主环境去执行,就比如说setTimeout这种函数交给宿主环境去执行,执行完成之后是会将最终setTimeout的回调函数返回给任务队列的,然后这个时候如果调用栈中的代码都执行完了,调用栈就会看一下任务队列中是否有任务,如果有任务就会执行对应的任务,如果说任务队列进栈之后发现又是一个异步任务这个时候也就会再次放到宿主环境中,然后循环往复。

3.es5之后提出了promise之后第一就解决了回调地狱的问题,因为异步调用的实质就是有了浏览器中间层去做操作(比如说你使用了一个定时器的话,实质是调用了浏览器的定时模块,两秒钟之后就会将定时器的callback返回给js引擎去执行来达到异步,又比如说网络请求也就是浏览器网络模块的内容去处理,并最终返回给js引擎),并返回callback函数,所以异步也就是通过回调函数来体现的。那么es6之后为了区分这种setTimeOut这种需要宿主环境的就变为宏任务队列,以及不需要宿主环境的就是js自身发起的异步任务例如promise里的then和catch称为微任务队列。

通过添加两个队列之后,事件循环机制就会变得更有意思了,当初始化代码执行完毕之后,被分配为异步执行的代码会被分为两类,一类是宏任务另外一类是微任务,js会先执行微任务队列,进而执行宏任务队列。

图中没有给注释的就是直接执行的,promise内部的代码也是同步执行的,当遇到resolve之后会将then方法内部的回调函数加入到微任务队列中,然后await后边的代码也会被加到微任务队列中,因此结果就是为

其中Promise{<fulfilled>:undefined}就是浏览器返回的默认值,与本题无关,然而我们会发现其中456无故消失的原因,其实是因为,在456那个promise中我并未给他添加resolve参数,这就导致那段输出456的回调函数失效。

大家可以通过这个网站去练练手观察整个事件循环的过程(但是我使用的时候非常卡):JS Visualizer 9000

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值