javascript 事件循环
JavaScript的运行顺序就是完全单线程的异步模型:同步在前,异步在后。所有的异步任务都要等待当前的同步任务执行完毕之后才能执行。
在JavaScript中,任务可以分为宏任务和微任务两种类型。宏任务是指需要在任务队列中排队执行的任务,而微任务是指在当前任务执行结束后立即执行的任务。
常见的宏任务包括:
script(整体代码)、setTimeout、setInterval、setImmediate(Node.js独有)、I/O操作、UI渲染等。
常见的微任务包括:
Promise.then()、MutationObserver、process.nextTick(Node.js独有)等。
拓展:
setTimeout是宿主浏览器发起的任务,一般会被放入宏任务
而Promise是由JS引擎发起的任务,会被放入微任务
第一次事件循环中,JS引擎会把整个script代码当成一个宏任务执行,执行完成之后,再检测本次循环中是否存在微任务,存在的话就依次从微任务的任务队列中读取执行完所有的微任务,再读取宏任务的任务队列中的任务执行,再执行所有的微任务,如此循环。
JS的执行顺序就是每次事件循环中的宏任务-微任务的不断切换。
当一个宏任务执行完成后,会检查是否有微任务需要执行,如果有就将所有微任务全部执行完毕,然后再执行下一个宏任务。因此,微任务的执行优先级要高于宏任务。
- JavaScript是单线程
- 执行内容分为普通代码(如 var a = 1),任务:宏任务(如setTimeout())和微任务(如Promise.then())
- 执行过程涉及栈(FILO)和队列结构(FIFO)
- JavaScript代码整体当作宏任务
- 解析代码时,普通代码先执行,遇到任务加入队列
- 代码执行时,按顺序:普通代码执行完成> 执行微任务队列全部微任务> 执行一个宏任务> 检查微任务是否执行完成,未完成,执行所有微任务> 执行一个宏任务> 检查微任务是否执行完成,未完成,执行所有微任务>...
举例1:
console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end'); 输出: script start script end promise1 promise2 setTimeout
举例2:
Promise.resolve().then(function(){ console.log('resolve1') setTimeout(function(){ console.log('setTimeout1') },0) }) setTimeout(function(){ console.log('setTimeout2') Promise.resolve().then(function(){ console.log('resolve2') }) },) 输出: resolve1 setTimeout2 resolve2 setTimeout1
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App