前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >javascript事件循环机制–event loop

javascript事件循环机制–event loop

作者头像
OECOM
发布2020-07-02 09:29:11
5030
发布2020-07-02 09:29:11
举报
文章被收录于专栏:OECOMOECOM

JS最初被设计用在浏览器中是单线程,因为如果浏览器中的JS是多线程的,会出现下面这个矛盾点:

那么现在有2个进程,process1 process2,由于是多进程的JS,所以他们对同一个dom,同时进行操作。 process1 删除了该dom,而process2 编辑了该dom,同时下达2个矛盾的命令,浏览器瞬间就感觉懵逼了。

对于单线程来说,代码的执行顺序为自上而下执行,如果上一行解析时间很长,那么下面的代码就会被阻塞。 对于用户而言,阻塞就意味着"卡死",这样就导致了很差的用户体验。所以js就引入了异步的概念。

在前面我介绍过一遍文章--javascript异步编程使用方法,现在要说的是js单线程是如何实现异步的。答案就是是通过的事件循环(event loop),理解了event loop机制,就理解了JS的执行机制。

先来看一下下面这段代码的执行顺序:

代码语言:javascript
复制
console.log(1)
setTimeout(function(){
    console.log(2)
},0)
console.log(3)

实际的运行结果为1,3,2

通过上面的运行结果我们可以看出,setTimeout并没有立即执行,而是等到满足了一定条件才去执行的,这类代码,我们叫异步代码。

所以,这里我们首先知道了JS里的一种分类方式,就是将任务分为:同步任务和异步任务。在这里,同步任务为主线程。

于是乎就产生了一种执行机制:

首先判断代码是同步还是异步,如果是同步则进入主线程,如果是异步代码就进入event table;

异步任务在event table中注册函数,当异步代码达到执行条件时,就被推入到event queue事件队列当中;

同步任务进入主线程后会一直执行,直到同步任务执行完毕,主线程才会出现空闲,此时会去事件队列中查找是否有可执行的异步任务,如果有就推入到主线程中开始执行。

以上的三步基本上就构成了一个事件的循环机制--event loop。

当然这并不是一个完整的时间循环机制,其中的异步任务也有宏任务和微任务的区别。

总的来说宏任务一般包括:整体script代码块,setTimeout,setInterval

微任务包括:Promise,process.nextTick,ajax等。

首先判断代码是同步还是异步,如果是同步则进入主线程,如果是异步则看是宏任务还是微任务,如果是宏任务就放入到宏任务的队列当中,如果是微任务就放入到微任务的队列当中;

异步代码达到执行条件后就进入到事件队列当中,在此,微任务有一个优先权,就是当微任务中有任务,宏任务在事件队列当中的顺序就会靠后,即使宏任务达到了运行条件,也不会执行;

同步任务进入主线程后会一直执行,直到同步任务执行完毕,主线程出现空闲,此时去事件队列中查找,发现有宏任务和微任务,此时会等待微任务执行完成才会执行宏任务,然后按顺序执行完成。

这就是一个完整的时间循环机制。

看完上面的循环机制,再来看下面这这段代码:

代码语言:javascript
复制
setTimeout(function(){
     console.log('定时器开始啦')
 });
 
new Promise(function(resolve){
     console.log('马上执行for循环啦');
     for(var i = 0; i < 10000; i++){
         i == 99 && resolve();
     }
 }).then(function(){
     console.log('执行then函数啦')
 });
 console.log('代码执行结束');

很明显,按照上面的说法,这里的执行结果应该是:马上执行for循环啦--代码执行结束---执行then函数啦--定时器开始啦

由此我们看出setTimeout并不是我们想的那样,我们认为设置时间为3000,就是3秒之后开始执行内部代码,但是这种说并不严谨,准确的解释是:3秒后,setTimeout里的函数被会推入event queue,而event queue(事件队列)里的任务,只有在主线程空闲时才会执行。如果主线程执行内容很多,执行时间超过3秒,比如执行了10秒,那么这个函数只能10秒后执行了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-01-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档