Javascript 事件循环event loop

都知道javascript是单线程,那么问题来了,既然是单线程顺序执行,那怎么作到异步的呢?javascript

咱们理解的单线程应该是这样的,排着一个个来,是同步执行。

in-the-queue.jpg

现实中js是这样的

setTimeout(function() {
            console.log(1);
        });
        new Promise(function(resolve, reject) {
            console.log(2)
            resolve(3)
        }).then(function(val) {
            console.log(val);
        })
        console.log(4)
        //执行结果为 二、四、三、1
复制代码

结果告诉咱们,js是单线程没错,不过不是逐行同步执行。java

那咱们就来解析一下既然有异步,那顺序是怎样的?这些执行顺序规则就是理解eventLoop的要点,继续往下。node

Kapture 2019-01-15 at 16.01.35.gif

上图为我录制的chrome控制代码台执行顺序,虽然能看出执行顺序但咱们仍是懵逼的,咱们不知道规则,不懂就要问。ajax

搜索了不少官方、我的博客获得了一堆词:js引擎、主线程、事件表、事件队列、宏任务、微任务,完全懵逼。。。chrome

不急不急一个个来,咱们进入刨根问底状态segmentfault

js引擎

总结一句话就是解析优化代码 **制定执行规则 具体规则往下看浏览器

主线程

总结一句话执行js引擎优化并排列顺序后的代码bash

事件表(event table)

执行代码过程当中,异步的回调,例如(setTimeout,ajax回调)注册回调事件到event table异步

事件队列

当事件回调结束,事件表(event table)会将事件移入到事件队列(event queue)函数

#宏任务和微任务

宏任务包含的事件
事件 浏览器 node
I/O
setTimeout
setInterval
setImmediate
requestAnimationFrame
微任务包含的事件
事件 浏览器 node
I/O
process.nextTick
MutationObserver
Promise.then catch finally

不少博客是这样说的: 浏览器会不断从task队列中按顺序取task执行,每执行完一个task都会检查microtask队列是否为空(执行完一个task的具体标志是函数执行栈为空),若是不为空则会一次性执行完全部microtask。而后再进入下一个循环去task队列中取下一个task执行

说实话不是太理解,那么我就以本身的方式去学习和理解

为了更好的理解咱们再看代码

console.log('1');
        setTimeout(function() {
            console.log('2');
            new Promise(function(resolve) {
                console.log('3');
                resolve();
            }).then(function() {
                console.log('4')
            })
        })
        new Promise(function(resolve) {
            console.log('5');
            resolve();
        }).then(function() {
            console.log('6')
        })

        setTimeout(function() {
            console.log('7');
            new Promise(function(resolve) {
                console.log('8');
                resolve();
            }).then(function() {
                console.log('9')
            })
        })
        //执行结果:一、五、六、二、三、四、七、八、9
复制代码

image.png
有图为证我没骗你 再来个动图咱们具体看看浏览器的执行顺序
eventLoop1.gif

首先js引擎,区分是直接执行(同步代码),再执行异步代码,若是是异步再区分是宏任务仍是微任务,分别放入两个任务队列,而后开始执行,每执行完一个宏任务,扫一遍微任务队列并所有执行,此时造成一次eventLoop循环。以此规则不停的执行下去就是咱们所听到的事件循环。

我再补充一点,能够理解js引擎一开始把整个script当作一个宏任务,这样里边的就更容易理解了,开始就执行script宏任务,解析到宏任务里边又包含同步代码和异步代码(宏任务和微任务)依次执行顺序造成eventLoop。

欢迎吐槽点赞评论!

文章参考学习: www.jianshu.com/p/12b9f73c5… juejin.im/post/59e85e… segmentfault.com/a/119000001…

相关文章
相关标签/搜索