顺序:同步任务->微任务->ui渲染->宏任务
eg:
console.log(1)//任务1
setTimeout(() => {
console.log(2); // 宏任务2
}, 0);
new Promise((resolve, reject) => {
console.log(3)//任务3
resolve(4)
}).then(resolve => console.log(resolve)) // 微任务4
console.log(5);//任务5
//1 3 5 4 2
在上述例子中任务1、3、5都是属于同步任务,按照代码顺序先后执行。
执行到 setTimeout时由于 setTimeout属于宏任务等待时间到达或成功后,将回调的结果放入到宏队列中等待同步任务和微任务以及ui渲染执行结束后执行
执行到第五行代码时,返回的对象属于promise属于微任务,放入微任务队列等待同步任务执行完后执行
eg:
console.log('1');//同步任务1
setTimeout(() => {
console.log('2');//宏任务1里的同步任务1
Promise.resolve().then(() => {
console.log('3');//宏任务1里的微任务1
})
new Promise((resolve) => {
console.log('4');宏任务1里的同步任务2
resolve();
}).then(() => {
console.log('5')//宏任务1里的微任务2
})
})//宏任务1
new Promise((resolve) => {
console.log('7');//同步任务2
resolve();
}).then(() => {
console.log('8')//微任务1
})
setTimeout(() => {
console.log('9');//宏任务2里的同步任务1
Promise.resolve().then(() => {
console.log('10');//宏任务2里的微任务1
})
new Promise((resolve,reject) => {
console.log('11');//宏任务2里的同步任务2
reject();
}).then(() => {
console.log('12')//此处为resolve对应的方法,所以不执行
})
})//宏任务2
new Promise((resolve) => {
console.log('13');//同步任务3
resolve();
}).then(() => {
console.log('14')//微任务2
})
// 1 7 13 8 14 2 4 3 5 9 11 10
// 没有 12 , 因为 reject 了。
上例为浏览器的事件执行机制,前面相同,但当遇到开始执行宏任务时会优先执行宏任务里的微任务等到微任务队列为空时再执行下一个宏任务。
eg
async function async1() {
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2') // 3
}
console.log('script start')
setTimeout(function () {
console.log('setTimeout0')
}, 0)
setTimeout(function () {
console.log('setTimeout3')
}, 3)
async1();
new Promise(function (resolve) {
console.log('promise1')
resolve();
console.log('promise2')
}).then(function () {
console.log('promise3')
})
console.log('script end')
// script start
// async1 start
// async2
// promise1
// promise2
// script end
// async1 end
// promise3
// setTimeout0
// setTimeout3