js 事件循环理解

(注:图片来自https://juejin.im/post/5d5b4c2df265da03dd3d73e5#heading-5)

JavaScript是单线程的,所以在同一时刻只能做一件事,为了防止页面中有某些耗时的任务执行时间过长造成页面假死,js把任务的执行模式划分成了两种,分别是同步模式和异步模式。异步模式包含宏任务和微任务。

宏任务的优先级为:setTimeout>setInterVal>setImmediate>I/O

微任务的优先级为:promise.nextTick>promise>MutationObserver

执行顺序的规则:

首先JavaScript代码从上至下遇到定时器等宏任务会加入到宏任务队列,遇到promise.then等微任务会加入到微任务队列。等到主执行栈的同步代码执行完毕,会清空微任务队列,先加入的先执行后加入的后执行。清空微任务队列后去检查宏任务队列,每次只取出一个宏任务执行,执行完毕再次清空微任务队列,清空完毕再去检查宏任务队列。

下面举例讲解:

console.log('global');

setTimeout(function() { 
	console.log('setTimeout1');    
	new Promise(function(resolve) {        
		console.log('setTimeout1_promise');
        resolve();
    }).then(function() {       
	console.log('setTimeout1_promiseThen')
    })
    process.nextTick(function() {  
	console.log('setTimeout1_nextTick');
    })
},0);
new Promise(function(resolve) {    
	console.log('promise1');
    resolve();
}).then(function() {    
	console.log('promiseThen1');
})

setImmediate(function() {    
	console.log('setImmediate1');
setTimeout(function(){
	console.log("last")
	},0);
	setImmediate(function() { 
	console.log('setImmediate3');
	})
})

setImmediate(function() { 
	console.log('setImmediate2');
})

process.nextTick(function() {    
	console.log('nextTick');
})
new Promise(function(resolve) {    
	console.log('promise2');
    resolve();
}).then(function() {    
	console.log('promiseThen2')
})

setTimeout(function() {
	console.log('setTimeout2');
},0)

1. 首先执行整体代码,输出global;

2. 遇到setTimeout任务,将其加入到宏任务,此时

宏任务为:setTimeout1

微任务为空

3. 遇到promise,输出promise1,将其异步方法放入微任务中,此时

宏任务为:setTimeout1

微任务为:promise1

4. 遇到setImmediate,放入宏任务中,此时

宏任务为:setTimeout1

                  setImmediate1,setImmediate2

微任务为:promise1

5. 遇到promise.nextTick,放入微任务队列,此时

宏任务为:setTimeout1

                  setImmediate1,setImmediate2

微任务为:promise1

                  nextTick1

6. 遇到promise,输出promise2,将其异步回调放入微任务中,此时

宏任务为:setTimeout1

                  setImmediate1,setImmediate2

微任务为:promise1,promise2

                  nextTick1

7. 遇到setTimeout,放入宏任务中,此时

宏任务为:setTimeout1,setTimeout2

                  setImmediate1,setImmediate2

微任务为:promise1,promise2

                  nextTick1

第一轮循环结束。

第二轮循环:

1. 先执行微任务,nextTick优先级高,输出nextTick

2. 按队列先进先出,promise1的then执行,输出promiseThen1

3. promise2的then执行,输出promiseThen2

4. 微任务结束,开始执行宏任务,遇到setImmediate,将其加入下一轮循环;

5. 执行setTimeout1,输出setTimeout1,遇到setTimeout1_promise,输出setTimeout1_promise,将其异步加入到微任务,此时:

宏任务:

setImmediate1,setImmediate2

微任务:

setTimeout1_promise

6. 遇到process.nextTick,加入微任务,此时:

宏任务:

setImmediate1,setImmediate2

微任务:

setTimeout1_promise

setTimeout1_nextTick

7. 执行setTimeout2的任务,输出setTimeout2

本轮结束,进入下一轮循环。

1. 执行微任务,nextTick>promise,输出setTimeout1_nextTick

2. 执行setTimeout_promise的then回调,输出setTimeout1_promiseThen

3. 执行setImmediate1,输出setImmediate1,遇到setTimeout和setImmediate,加入宏任务中;

4. 执行setImmediate2,输出setImmediate2

本轮结束

1. setTimeout和setImmediate都在setImmediate中,执行顺序不定,所以lastsetImmediate3顺序不定,最后的输出为:

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值