Mythos推理基底:大模型跨文档一致性验证技术解析
2026/6/14 9:12:01
JavaScript 是单线程的,这意味着它一次只能执行一个任务。为了处理异步操作,JavaScript 使用事件循环机制。
console.log('1. 同步任务开始');setTimeout(()=>{console.log('2. setTimeout 回调');},0);Promise.resolve().then(()=>{console.log('3. Promise.then 回调');});console.log('4. 同步任务结束');console.log('1. 同步任务开始')压入调用栈,立即执行,输出1setTimeout压入调用栈,Web API 开始计时(0ms),回调函数放入宏任务队列Promise.resolve().then()压入调用栈,.then()的回调函数放入微任务队列console.log('4. 同步任务结束')压入调用栈,立即执行,输出4此时状态:
[Promise.then回调][setTimeout回调]console.log('3. Promise.then 回调'),输出3setTimeout回调,输出21 4 3 2console.log('script start')asyncfunctionasync1(){awaitasync2()console.log('async1 end')}asyncfunctionasync2(){console.log('async2 end')}async1()setTimeout(function(){console.log('setTimeout')},0)newPromise(resolve=>{console.log('Promise')resolve()}).then(function(){console.log('Promise1')})async函数总是返回一个 Promiseawait会暂停 async 函数的执行,直到 Promise 解决await后面的代码相当于放在.then()中,属于微任务console.log('script start')→ 输出script start
定义函数async1和async2(不执行)
调用async1()
async1,遇到await async2()async2()→console.log('async2 end')→ 输出async2 endawait暂停执行,console.log('async1 end')被包装成微任务放入微任务队列setTimeout→ 回调函数放入宏任务队列
执行new Promise
console.log('Promise')是同步代码 → 输出Promiseresolve()执行,.then()的回调放入微任务队列此时状态:
[async1 end, Promise1](注意顺序!)[setTimeout回调]调用栈为空,执行微任务
按入队顺序执行微任务:
console.log('async1 end')→ 输出async1 endconsole.log('Promise1')→ 输出Promise1微任务队列清空
setTimeout回调 → 输出setTimeoutscript start → async2 end → Promise → async1 end → Promise1 → setTimeout那么到此,应该是可以理解到事件循环的感觉了,那接下来我们就开始看看事件循环的完整逻辑
setTimeout、setIntervalsetImmediate(Node.js)requestAnimationFrame(浏览器)Promise.then()、.catch()、.finally()process.nextTick()(Node.js,优先级最高)MutationObserver(浏览器)queueMicrotask()1. 执行一个宏任务(script标签内容) 2. 执行过程中遇到异步任务: - 宏任务 → 放入宏任务队列 - 微任务 → 放入微任务队列 3. 当前宏任务执行完毕 4. 检查微任务队列,依次执行所有微任务 5. 如有必要,进行UI渲染 6. 从宏任务队列取出下一个宏任务执行 7. 回到步骤3,形成循环javascript
asyncfunctionexample(){awaitfoo()// 相当于 Promise.resolve(foo()).then(...)console.log('A')// 这部分在微任务队列中}javascript
// 测试微任务嵌套Promise.resolve().then(()=>{console.log('微任务1');Promise.resolve().then(()=>{console.log('微任务中的微任务');});}).then(()=>{console.log('微任务2');});// 输出顺序:微任务1 → 微任务中的微任务 → 微任务2javascript
// 测试多个宏任务setTimeout(()=>console.log('宏任务1'),10);Promise.resolve().then(()=>console.log('微任务1'));setTimeout(()=>{console.log('宏任务2');Promise.resolve().then(()=>console.log('宏任务2中的微任务'));},1);Promise.resolve().then(()=>console.log('微任务2'));setTimeout(()=>{console.log('宏任务3');Promise.resolve().then(()=>console.log('宏任务3中的微任务'));},0);结果: 微任务1微任务2宏任务3宏任务3中的微任务 宏任务1宏任务2宏任务2中的微任务 为什么呢?聪明的你已经会了 一开始 微任务 放入 微任务1, 微任务2;然后宏任务放入 宏任务3这个时候, 计时器还没有到底100ms的时候, 打印微任务1、微任务2;然后微任务清空,开始 宏任务3, 放入微任务 宏任务3中的微任务,然后打印宏任务3中的微任务; 然后计时器到了,打印宏任务1、宏任务2、放入微任务, 打印宏任务2中的微任务;大概就是这种感觉async/await本质是 Promise 的语法糖,await后面的代码是微任务