事件循环通过调用栈与任务队列协作调度异步任务:同步代码入栈执行,异步回调分入宏任务队列(如setTimeout)和微任务队列(如Promise.then);每轮先清空微任务,再取一个宏任务执行;Node.js中process.nextTick优先级高于微任务。

JavaScript中的事件循环负责协调同步代码执行与异步任务调度,确保主线程不被阻塞。以下是事件循环处理异步操作的核心机制:
一、调用栈与任务队列的协作
JavaScript引擎执行同步代码时将函数压入调用栈;当遇到异步操作(如setTimeout、Promise.then),其回调函数不会立即执行,而是被放入对应的任务队列中等待调度。事件循环持续检查调用栈是否为空,一旦为空,就从任务队列中取出一个回调并推入调用栈执行。
1、同步代码逐行执行,每调用一个函数就将其压入调用栈。
2、遇到setTimeout或Promise时,浏览器或Node.js环境将回调注册到Web API或Promise微任务队列。
立即学习“Java免费学习笔记(深入)”;
3、当调用栈清空后,事件循环优先处理所有微任务队列中的回调(如Promise.then、queueMicrotask)。
4、微任务全部执行完毕后,事件循环再从宏任务队列(如setTimeout、setInterval、I/O回调)中取出一个任务执行。
二、宏任务与微任务的区分
事件循环严格区分两类异步任务:宏任务(macrotask)和微任务(microtask)。宏任务每次循环只执行一个,而微任务会在每次宏任务结束后全部清空。这种优先级设计保证了Promise等异步操作的响应及时性。
1、宏任务包括:script整体代码、setTimeout、setInterval、setImmediate(Node.js)、I/O、UI渲染。
2、微任务包括:Promise.then/catch/finally回调、queueMicrotask、MutationObserver回调。
3、执行顺序为:宏任务 → 清空全部微任务 → 下一个宏任务 → 再清空全部微任务。
三、Promise状态转换触发微任务入队
Promise对象的状态变化(pending → fulfilled 或 pending → rejected)会自动将关联的then/catch回调加入微任务队列,而非立即执行。这使得Promise链式调用具有确定的执行时机,不受外部同步代码干扰。
大小仅1兆左右 ,足够轻便的商城系统; 易部署,上传空间即可用,安全,稳定; 容易操作,登陆后台就可设置装饰网站; 并且使用异步技术处理网站数据,表现更具美感。 前台呈现页面,兼容主流浏览器,DIV+CSS页面设计; 如果您有一定的网页设计基础,还可以进行简易的样式修改,二次开发, 发布新样式,调整网站结构,只需修改css目录中的css.css文件即可。 商城网站完全独立,网站源码随时可供您下载
1、new Promise(executor)立即执行executor函数,其中resolve或reject为同步调用。
2、在executor中调用resolve(value)后,该Promise变为fulfilled状态,并将所有注册的then回调推入微任务队列。
3、即使在同步代码中连续调用多个Promise.then,它们也全部进入当前轮次的微任务队列,按注册顺序执行。
四、setTimeout与Promise.then的执行顺序差异
尽管两者均为异步,但因所属队列不同,执行优先级存在本质区别。setTimeout回调属于宏任务,而Promise.then回调属于微任务,因此后者总在前者之前执行(在同一事件循环轮次中)。
1、执行console.log('start')后,遇到setTimeout(() => console.log('timeout'), 0),回调被放入宏任务队列。
2、接着执行new Promise(resolve => { console.log('promise'); resolve(); }).then(() => console.log('then')),then回调被放入微任务队列。
3、同步代码结束,先执行微任务队列中的'then',再执行宏任务队列中的'timeout'。
五、Node.js中process.nextTick的特殊优先级
在Node.js环境中,process.nextTick不属于标准微任务,但其回调拥有比Promise.then更高的执行优先级,会在当前操作完成后、任何其他微任务前执行。这一机制常用于错误传递和精细控制执行时机。
1、process.nextTick(callback)将callback插入nextTick队列,位于当前操作与微任务之间。
2、即使在Promise.then中调用process.nextTick,该回调仍会在then回调之前执行。
3、过度使用process.nextTick可能导致I/O饥饿,因其会延迟所有后续微任务和宏任务。









