文章目录一、先抛一个生活例子奶茶店的接单流程二、JS事件循环的核心概念人话版三、事件循环的执行流程带代码例子1. 基础代码示例2. 执行过程拆解跟着店员的节奏走3. 进阶宏任务 vs 微任务优先级别代码示例执行顺序四、一张图总结事件循环流程五、新手常见误区六、实战小练习检验是否理解总结一、先抛一个生活例子奶茶店的接单流程先不聊代码咱们先看个日常场景你去奶茶店点单店员只有1个对应JS的单线程所有订单都得排着来你点了一杯珍珠奶茶同步任务店员立刻接单、配原料、做奶茶做完才能接下一个单下一个顾客点了现煮的芋泥奶茶需要等10分钟异步任务店员不会傻等会先记下这个订单给顾客一个取餐号然后继续接下一个简单的订单比如打包现成的柠檬水等芋泥煮好后异步任务完成店员会喊取餐号优先处理这个订单回调执行。JS的事件循环本质就是这个“接单-处理-回调”的流程核心解决的是“单线程如何处理耗时任务”的问题。二、JS事件循环的核心概念人话版先把几个关键术语翻译成大白话避免一上来就懵专业术语人话解释对应奶茶店场景单线程JS只有一个“执行线程”同一时间只能做一件事奶茶店只有1个店员同步任务立刻能做完、不耗时的任务做现成的柠檬水、打包奶茶异步任务耗时的任务比如网络请求、定时器、DOM事件煮芋泥、等外卖小哥取餐调用栈存放正在执行的同步任务“先进后出”店员手里正在处理的订单清单任务队列存放等待执行的异步回调任务奶茶店的待取餐订单列表事件循环持续检查“调用栈是否为空”空了就从任务队列取任务执行店员不停看手里的活干完没干完就去待取餐列表拿订单三、事件循环的执行流程带代码例子咱们把奶茶店的流程对应到代码里一步一步看执行过程1. 基础代码示例// 同步任务立刻执行console.log(1. 点单成功);// 异步任务定时器耗时任务setTimeout((){console.log(2. 芋泥奶茶做好了);},0);// 同步任务立刻执行console.log(3. 打包柠檬水完成);2. 执行过程拆解跟着店员的节奏走第一步JS引擎店员先执行调用栈里的同步任务执行console.log(1. 点单成功)→ 输出1. 点单成功遇到setTimeout这是异步任务JS引擎不等待直接把回调函数() {console.log(2. 芋泥奶茶做好了)}丢到“任务队列”里继续执行下一个同步任务执行console.log(3. 打包柠檬水完成)→ 输出3. 打包柠檬水完成第二步调用栈空了事件循环开始工作事件循环检查到“调用栈为空”就去任务队列里取第一个回调任务放到调用栈执行执行console.log(2. 芋泥奶茶做好了)→ 输出2. 芋泥奶茶做好了最终输出顺序1. 点单成功 3. 打包柠檬水完成 2. 芋泥奶茶做好了3. 进阶宏任务 vs 微任务优先级别刚才的例子是“宏任务”实际还有优先级更高的“微任务”咱们继续用奶茶店举例宏任务普通异步任务定时器、DOM事件、网络请求、script整体代码→ 对应“普通待取餐订单”微任务高优先级异步任务Promise.then/catch/finally、async/await、queueMicrotask→ 对应“外卖订单优先处理”核心规则事件循环每次处理完调用栈的同步任务后会先把所有微任务执行完再执行一个宏任务。代码示例执行顺序console.log(1. 点单成功);// 同步任务// 宏任务setTimeout((){console.log(2. 普通订单芋泥奶茶做好了);},0);// 微任务Promise.resolve().then((){console.log(3. 外卖订单芝士奶盖做好了);});console.log(4. 打包柠檬水完成);// 同步任务执行结果1. 点单成功 4. 打包柠檬水完成 3. 外卖订单芝士奶盖做好了 2. 普通订单芋泥奶茶做好了拆解先执行同步任务输出 1 → 4调用栈空了先执行所有微任务输出 3微任务执行完再执行宏任务输出 2四、一张图总结事件循环流程否是开始执行调用栈中的同步任务调用栈为空执行所有微任务从宏任务队列取一个任务执行五、新手常见误区误区1setTimeout(fn, 0)会立刻执行→ 错0毫秒不代表立刻只是把回调丢到任务队列要等同步任务微任务都执行完才会轮到它。误区2JS有多线程→ 错JS主线程是单线程的异步任务的“等待阶段”比如定时器计时、网络请求是浏览器/Node的其他线程处理的等完成后才把回调丢到任务队列。误区3微任务和宏任务是一起排队的→ 错微任务有单独的队列优先级远高于宏任务必须等所有微任务执行完才会处理宏任务。六、实战小练习检验是否理解看代码说输出顺序测试自己的掌握程度console.log(a);setTimeout((){console.log(b);Promise.resolve().then((){console.log(c);});},0);Promise.resolve().then((){console.log(d);setTimeout((){console.log(e);},0);});console.log(f);答案先自己想再看a → f → d → b → c → e总结JS事件循环的核心是单线程异步因为单线程只能逐行执行所以用事件循环处理耗时的异步任务避免阻塞执行优先级同步任务 微任务 宏任务每次调用栈清空后先执行完所有微任务再处理一个宏任务记住奶茶店的例子店员JS线程先做能立刻完成的活同步耗时的活记下来异步任务队列干完手头的活后先处理优先订单微任务再处理普通订单宏任务。用这个思路去看JS的异步代码不管是定时器、Promise还是async/await都能一眼看透执行顺序啦