在js中,任务队列是异步编程的核心概念,它允许js引擎按照特定的顺序执行代码片段,即使js本身是单线程的。任务队列通过事件循环(Event Loop)来管理,确保代码的执行顺序和时机
1、js任务队列中分为同步和异步任务, 异步任务中分为宏任务和微任务
宏任务:script 标签、setTimeout、setInterval、ajax、事件回调
微任务:Promise.then/catch/finally、process.nextTick(Node.js 环境)、MutationObserver(浏览器环境)、queueMicrotask
浏览器在事件循环中的一个独立阶段:
UI渲染 (执行时机:在当前宏任务和所有微任务执行完毕后,浏览器会进行 UI 渲染,渲染引擎会在后台处理渲染任务,而不会阻塞 Js 的执行) (ps:只有当有视觉变化或达到刷新率时,浏览器才会进入渲染阶段)
requestAnimationFrame (执行时机:浏览器下一次渲染之前)
2、js 事件循环机制,循环逻辑
- 执行一个宏任务(例如 script 标签中的代码、setTimeout、setInterval 等)
- 执行当前宏任务中的同步代码
- 执行当前宏任务中的微任务(例如 Promise 的 then 回调)
- UI 渲染(如果有必要)
- 进入下一轮事件循环
3、以下代码为例, 一共为5轮循环
- 执行 script 这个宏任务,然后打印 1 5 12 6 11
- 执行第1个 setTimeout,然后打印 2 4
- 执行第2个 setTimeout,然后打印 7
- 执行第1个 setTimeout 中的嵌套的 setTimeout,然后打印 3
- 执行第2个 setTimeout 中的嵌套的 setTimeout,然后打印 8 10 9
打印结果为:1 5 12 6 11 2 4 7 3 8 10 9
console.log(1);
setTimeout(function () {
console.log(2);
setTimeout(() => {
console.log(3);
}, 0);
Promise.resolve().then(function () {
console.log(4);
});
}, 0);
// new一个Promise对象是同步任务,Promise中then,catch等方法是异步微任务
new Promise(function (resolve) {
console.log(5);
resolve();
}).then(function () {
console.log(6);
})
setTimeout(function () {
console.log(7);
setTimeout(function () {
new Promise(function (resolve) {
console.log(8);
resolve();
}).then(function () {
console.log(9);
})
console.log(10);
}, 0);
}, 0);
Promise.resolve().then(function () {
console.log(11);
});
console.log(12);
详细解释:
第一轮事件循环:
执行 script 宏任务中的同步代码:
console.log(1); 输出 1
new Promise(function (resolve) { console.log(5); resolve() }) 输出 5
console.log(10); 输出 12
执行微任务:
.then(function () {console.log(6);}) 输出 6
Promise.resolve().then(function () { console.log(11) }) 输出 11
UI 渲染(如果有必要)
进入下一轮事件循环

1109

被折叠的 条评论
为什么被折叠?



