主线程被10秒加密计算阻塞时,所有微任务(如Promise.then)和宏任务(如setTimeout)均延迟执行,页面完全无响应;解决方法是使用Web Worker、分片计算或原生异步API。

主线程被复杂加密计算阻塞10秒,微任务会一直等待,直到计算完成、同步代码全部执行完毕后,才集中、立即执行。
微任务不会“穿插”执行
微任务(如 Promise.then、queueMicrotask)不是随时插入执行的。它们只在每个宏任务结束之后、下一个宏任务开始之前批量清空。如果当前宏任务(比如一个耗时10秒的 for 循环或加密函数)没结束,微任务队列就始终处于“挂起”状态,哪怕队列里已经堆积了几十个 Promise 回调,也一个都不会执行。
阻塞期间所有异步回调都被延迟
不只是微任务,所有异步任务都会被推迟:
- Promise.then / .catch / queueMicrotask:进微任务队列,但要等10秒后才执行
- setTimeout(fn, 0):进宏任务队列,得等当前宏任务 + 所有已排队微任务执行完,才能轮到它
- MutationObserver:同属微任务,一样被卡住
- 用户点击、fetch响应、键盘事件:回调进入对应任务队列,但同样无法触发,页面表现为完全无响应
实际表现就是“假死”
浏览器主线程被独占10秒,意味着:
立即学习“Java免费学习笔记(深入)”;
- 页面渲染冻结(没有 UI 更新、动画、滚动)
- 控制台日志只有加密结束后才一口气输出(包括所有微任务和后续宏任务)
- 即使 setTimeout 设为 0ms,也会排在加密完成+微任务清空之后
- 没有任何异步逻辑能“打断”或“中断”这个同步计算
解决思路是避开主线程阻塞
真正需要10秒级计算时,不能放在主线程上:
- 用 Web Worker 在后台线程运行加密,主线程保持响应
- 把大计算拆成小块,中间用 setTimeout 或 requestIdleCallback 让出主线程
- 优先使用浏览器原生 API(如 SubtleCrypto),它们内部自动走异步线程


















