宏任务macrotasks:setTimeout、setInterval、I/O、UI渲染
微任务microtasks:Promise、 process.nextTick、Object.observe、 MutationObserver
微任务优先级高于宏任务。每一个事件循环都有一个微任务队列、一个或者多个宏任务队列。
console.log('同步代码1');
setTimeout(
()=>{
console.log('异步代码5,宏任务,优先级较低');
}
);
new Promise((resolve,reject)=>{
console.log('同步代码2')
resolve('Promise的回调')
}).then(data=>{
console.log('异步代码4,微任务,优先级较高',data)
})
console.log('同步代码3');
console.log('script start');
async function async1() {
await async2();
console.log('async1 end'); // 这里的代码相当于promise.resolve().then(里面)
}
async function async2() {
console.log('async2 end');
}
async1();
setTimeout(function () {
console.log('setTimeout')
}, 0)
new Promise(resolve => {
console.log('Promise');
resolve()
})
.then(function () {
console.log('promise1')
})
.then(function () {
console.log('promise2')
})
console.log('script end')
function delay(duration) {
var start = Date.now()
while(Date.now() - start < duration){}
}
setTimeout(function(){
console.log(1)
}, 0)
delay(1000)
console.log(2)
// 等待一秒之后输出2 1
setTimeout(function(){
console.log(1)
}, 0)
Promise.resolve().then(function(){
console.log(2)
})
console.log(3)
// 3 2 1
function a(){
console.log(1)
Promise.resolve().then(function(){
console.log(2)
})
}
setTimeout(function(){
console.log(3)
Promise.resolve().then(a)
}, 0)
Promise.resolve().then(function(){
console.log(4)
})
console.log(5)
// 5 4 3 1 2
1.如果执行函数栈的时候出现while(true) 会阻塞渲染。
2.如果微任务请求数据一直执行,不交回执行权,递归调用微任务,会阻塞渲染。
3.如果不断的执行下一个task,递归调用宏任务,不会阻塞渲染。
<body>
<input type="text">
<button id="syn1">同步阻塞</button>
<button id="syn2">微任务阻塞</button>
<button id="syn3">宏任务阻塞</button>
<script>
// 同步阻塞
document.querySelector('#syn1').onclick=function(){
while(true){}
}
// 微任务阻塞
function micro() {
Promise.resolve('ok').then((data)=>{
micro();
})
}
document.querySelector('#syn2').onclick=function(){
micro();
}
// 宏任务不阻塞
function macro() {
setTimeout(()=>{
console.log('执行宏任务了!!')
macro();
})
}
document.querySelector('#syn3').onclick=function(){
macro();
}
</script>
</body>