前言
宏任务:
setTimeout
,setInterval
,Ajax
,DOM
事件
微任务:Promise
,async/await
。
优先级:微任务
执行要比宏任务
要早。注:
同步任务会和微任务按照出场顺序先后执行,最后执行宏任务
。
同步和异步
console.log('123')
alert('阻塞')
console.log('等待中。。。。')
console.log('1')
//计时器
setTimeout(()=>{
alert('111')
},5000)
console.log('2')
- 定时任务:setTimeout,setInverval
- 网络请求:ajax请求,动态
<img>
加载- 事件绑定
任务列队和event loop(事件循环)
单线程就意味着,所有的任务都要排队,前一个结束,才会执行后面的任务。如果列队是因为计算量大,CPU忙不过来,倒也算了。但是更多的时候,CPU是闲置的,因为IO设备处理得很慢,例如
ajax读取网络数据。js设计者便想到,主线程完全可以不管IO设备,将其挂起,然后执行后面的任务。等后面的任务结束掉,在反过头来处理挂起的任务。
所有的同步任务都在主线程上执行,行成一个执行栈。
除了主线程之外,还存在一个任务列队,只要异步任务有了运行结果,就在任务列队中植入一个时间标记。
主线程完成所有任务(执行栈清空),就会读取任务列队,先执行微任务队列在执行宏任务队列。
重复上面三步。
执行顺序
同步任务会和微任务按照出场顺序先后执行,最后执行宏任务
//第一个执行
console.log('---start---');//第一轮主线程
setTimeout(() => {
//第五个执行
console.log('setTimeout'); // 将回调代码放入个宏任务队列,第二轮宏任务执行
}, 0);
new Promise((resolve, reject) => {
//第二个执行
console.log('---Promise第一轮微任务同步执行---');//第一轮微任务同步执行
resolve()
}).then(() => {
//第四个执行
console.log('Promise.then实例成功回调执行'); // 将回调代码放入微任务队列,第一轮宏任务执行完后立即执行
});
//第三个执行
console.log('---end---');//第一轮主线程结束
给大家留个练习自己看看
// 宏任务队列 1
setTimeout(() => {
// 宏任务队列 2.1
console.log('timer_1');
setTimeout(() => {
// 宏任务队列 3
console.log('timer_3')
}, 0)
new Promise(resolve => {
resolve()
console.log('new promise')
}).then(() => {
// 微任务队列 1
console.log('promise then')
})
}, 0)
setTimeout(() => {
// 宏任务队列 2.2
console.log('timer_2')
}, 0)
console.log('========== Sync queue ==========')