javascript事件循环先执行同步代码,再清空所有微任务,最后执行一个宏任务,循环往复;同步代码属首个宏任务,promise.then等为微任务,settimeout等为宏任务,微任务总在宏任务间“插队”并全部执行完。

先执行同步代码,再清空微任务队列
JavaScript 引擎总是从调用栈开始执行同步任务。只要代码是直接写的、没被包裹在异步回调里,就属于当前宏任务的同步部分。等这段同步代码全部跑完、调用栈变空,引擎立刻转向微任务队列——不是只执行一个,而是把当前队列里所有微任务依次执行完,直到队列彻底为空。
常见微任务包括:
• Promise.then/catch/finally 的回调
• queueMicrotask() 注册的函数
• MutationObserver 的回调(浏览器环境)
一个宏任务执行完,才取下一个宏任务
微任务队列清空后,事件循环才会去宏任务队列里取一个任务执行。注意:每次只取一个,哪怕队列里有十个 setTimeout,也得等这个执行完、再次清空微任务,才轮到下一个。
典型宏任务有:
• script 整体(页面加载时的第一个宏任务)
• setTimeout 和 setInterval 的回调
• I/O 回调(如 fetch 完成、文件读取结束)
• UI 渲染(浏览器在微任务之后、下个宏任务之前可能触发)
微任务可以“嵌套生成”,但仍在本轮清空
在微任务执行过程中,如果又创建了新的微任务(比如在 Promise.then 里再写一个 Promise.resolve().then),这个新任务会被追加到当前微任务队列末尾,继续执行,不会等到下一轮。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
例如:
Promise.resolve().then(() => {
console.log(1);
Promise.resolve().then(() => console.log(2));
});
输出一定是 1 → 2,中间不会插入任何宏任务。
定时器的延迟时间决定入队时机,不是代码顺序
多个 setTimeout 的执行顺序,不看谁先写,而看谁的延迟时间更短、谁先到期。比如:
setTimeout(() => console.log('a'), 10);
setTimeout(() => console.log('b'), 0);
即使 a 先写,b 仍会先入队、先执行,因为它的延迟为 0,更早满足入队条件。
注意:浏览器对 setTimeout(0) 有最小间隔限制(通常 ≥4ms),所以实际执行仍会有微小延迟。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










