Eventloop(事件循环)

Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。

JavaScript代码的执行过程中,除了依靠函数调用栈来搞定函数的执行顺序外,还依靠任务队列(task queue)(先进先出)来搞定另外一些代码的执行

Javascript单线程任务被分为同步任务和异步任务,同步任务会在调用栈中按照顺序等待主线程依次执行(代码从上到下的执行),异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候(调用栈被清空),被读取到栈内等待主线程的执行。

一个线程中,事件循环是唯一的,但是任务队列可以拥有多个。

任务队列又分为macro-task(宏任务)与micro-task(微任务),在最新标准中,它们被分别称为task与jobs。

macro-task大概包括:script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering。

micro-task大概包括: process.nextTick, Promise, Object.observe(已废弃), MutationObserver(html5新特性)

setTimeout/Promise等我们称之为任务源。而进入任务队列的是他们指定的具体执行任务。

来自不同任务源的任务会进入到不同的任务队列。其中setTimeout与setInterval是同源的。

事件循环的顺序,决定了JavaScript代码的执行顺序。它从script(整体代码)开始第一次循环(即宏任务)。之后全局上下文进入函数调用栈。直到调用栈清空(只剩全局),然后执行所有的micro-task(微任务)。当所有可执行的micro-task(微任务)执行完毕之后。循环再次从macro-task(宏任务)开始,找到其中一个任务队列执行完毕,然后再执行所有的micro-task(微任务),这样一直循环下去。

一个简单的例子:

setTimeout(function(){

      console.log('timeout1');

})

new Promise(function(resolve){

       console.log('promise1');

       for(var i =0; i <1000; i++) {

              i ==99&& resolve();

       }

console.log('promise2');

}).then(function(){

       console.log('then1');

})

console.log('global1')
//打印的顺序
// promise1

// promise2

// global1

// then1timeout1

具体可以参考:https://www.jianshu.com/p/6a1932dbbc95      https://zhuanlan.zhihu.com/p/55511602  这二篇文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章