刚写完一个抽奖转盘,点一下按钮,页面直接卡成PPT,老板在旁边盯着我,我头皮发麻。
原来不是代码写错,是JavaScript那口“单锅”又被我塞爆了。
我就纳闷:它明明说自己是单线程,怎么又蹦出“事件循环”这种听起来像作弊的东西?
先把锅甩给浏览器。
它把任务分成两堆:
一堆叫宏任务,setTimeout、点击事件、整段定时器全塞这儿;
另一堆叫微任务,Promise.then、async/await 的尾巴全塞这儿。
浏览器先干完手里同步的活,然后一口气把微任务全清掉,再去宏任务里挑一个。
所以上面那段代码:
console.log('同步') → Promise.then('微任务') →setTimeout('宏任务')
顺序死死卡死,谁插队谁尴尬。
我昨天刚踩坑。
为了省时间,我把十万条数据一股脑丢进 for循环里算总价,结果页面直接冻住,连滚动条都罢工。
同事路过丢一句:拆成一千条一千条算,中间插个 setTimeout0,让浏览器喘口气。
我照做,卡顿肉眼可见地消失,老板以为我连夜学了魔法。
Node 那边更鸡贼。
老版本里 setImmediate 和 setTimeout 谁先跑全看脸,Node 11之后才跟浏览器对齐。
我上周在服务器跑脚本,日志里两条打印顺序天天变,差点把我逼成哲学家。
再补一刀:微任务别写太多。
我图省事,Promise.then 里再套 Promise.then,结果页面帧率掉到20,动画像翻书。
浏览器 UI渲染得等微任务全跑完,微任务一多,渲染就排队,用户以为网站挂了。
一句话收个尾:
别把单线程当借口,学会让任务排队、插队和轮休,页面才不闹脾气,老板也不皱眉。