JavaScript事件循环机制
JavaScript是一种单线程、非阻塞的语言,这是由于它当初的设计就是用于和浏览器交互的:
单线程:
JavaScript设计为单线程的原因是,最开始它最大的作用就是和DOM进行交互,试想一下,如果JavaScript是多线程的,那么当两个线程同时对DOM进行一项操作,例如一个向其添加事件,而另一个删除了这个DOM,此时该如何处理呢?因此,为了保证不会 发生类似于这个例子中的情景,JavaScript选择只用一个主线程来执行代码,这样就保证了程序执行的一致性。
非阻塞:
当代码需要进行一项异步任务(无法立刻返回结果,需要花一定时间才能返回的任务,如I/O事件)的时候,主线程会挂起(pending)这个任务,然后在异步任务返回结果的时候再根据一定规则去执行相应的回调。而JavaScript实现异步操作的方法就是使用Event Loop。
setTimeout(function () {
console.log(1);
});
new Promise(function(resolve,reject){
console.log(2)
resolve(3)
}).then(function(val){
console.log(val);
})
首先setTimeout和Promise中的then回调都是异步方法,而new Promise则是一个同步操作,所以这段代码应该首先会立即输出2;JavaScript将异步方法分为了marco task(宏任务:包括setTimeout和setInterval等)和micro task(微任务:包括new Promise等),在JavaScript的执行栈中,如果同时存在到期的宏任务和微任务,则会将微任务先全部执行,再执行第一个宏任务,因此,两个异步操作中then的回调会率先执行,然后才执行setTimeout的回调,因此会依次输出3、1,所以最终输出的结果就是2、3、1。
网友评论