JS 异步为什么要区分微任务和宏任务?有意义吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
ailuoliai
V2EX    程序员

JS 异步为什么要区分微任务和宏任务?有意义吗?

  •  
  •   ailuoliai 2020-07-06 20:45:15 +08:00 3878 次点击
    这是一个创建于 1972 天前的主题,其中的信息可能已经有所发展或是发生改变。

    定个优先级不就好了吗? 还搞 2 个异步 queue

    autoxbc
        1
    autoxbc  
       2020-07-06 20:52:38 +08:00
    所以楼主是不理解这个设计,还是理解了觉得不好
    ailuoliai
        2
    ailuoliai  
    OP
       2020-07-06 20:57:01 +08:00
    @autoxbc 刚看, 是先同步任务->所有微任务->宏任务这样吗?
    autoxbc
        3
    autoxbc  
       2020-07-06 21:05:22 +08:00
    @ailuoliai #2 是吧
    WhoAmIAndwhoAreU
        4
    WhoAmIAndwhoAreU  
       2020-07-06 21:11:01 +08:00
    微任务中产生了新的宏任务会在下一次 Event Loop 执行的微任务之前执行,明白?
    SilentDepth
        5
    SilentDepth  
       2020-07-06 21:20:37 +08:00
    因为两个 queue 比全部打散一起排优先级实现起来更容易
    JayLin1011
        6
    JayLin1011  
       2020-07-06 21:24:48 +08:00
    @ailuoliai 存在即合理。还有,所谓同步任务也是宏任务哦。
    xinleibird
        7
    xinleibird  
       2023-08-12 19:25:29 +08:00
    1. 同步任务和异步任务是周期性切换的:同步 -> 异步 -> 同步 -> 异步……

    2. 对于同步结构:代码在执行时,可执的部分被压入执行栈,子部分被继续分解压入,继续压入执行栈。分解完毕后,由栈顶逐一弹出,最后统一执行。这个部分在所有语言中的模型是一致的。

    3. 加入异步任务之后,就面临一个问题,在什么时机将异步任务中的同步部分插入到同步任务中? Javascript 采用的思路是以「是否由事件驱动」来做区分:
    3.1 「微任务队列」:对于 Promise 相关的异步任务,Javascript 不认为它是由事件驱动的。因此这些任务即使在同一个轮询周期内都回调了,它也认为是应该同一个周期进行响应的。表现就是只要在这个周期内响应的 Promise 的回调,它就按照顺序都按一般规则压入执行栈。
    3.2 「宏任务队列」:对于由事件驱动的异步任务,例如各种 UI 响应(点击啦,焦点啦之类的)、或者 UI 渲染、或者单纯的脚本加载之类的,Javascript 认为它们应该在一个轮询周期内只触发一个。(例如说,鼠标点击一个元素,它大概率会触发重绘或者重排,重绘重排同时是 UI 渲染,如果这个「宏任务队列」积压的任务过多,一次执行,则会有 UI 渲染错误的风险。这里仅是举例)将这个宏任务的回调压入执行栈。

    4. 这时候我们可以从「执行栈」和「两个异步队列」来看这个循环:
    (首先由 <script> 标签引入代码的过程是个宏任务,我们略过不提。仅此一次而已)
    4.1 脚本的中的代码顺序执行,同步代码则依次压入执行栈,异步回调代码按照分类分别放入「微任务队列」和「宏任务队列」。
    4.2 执行的焦点一直在执行栈之间切换。
    4.2.1 焦点在执行栈中时,则弹栈执行清空。
    4.2.2 焦点在异步队列时,则首先查看「微任务队列」,此时已响应的「微任务」会按队列顺序依次压入执行栈。然后会查看「宏任务队列」,将队列中排位靠前的一个「宏任务」压入执行栈。
    4.2.3 焦点再转回执行栈,然后再转回异步队列,由此循环。


    题外话,你把视角代入到「执行栈」就容易想清楚了。(静态的执行栈如何管理异步代码?)
    xinleibird
        8
    xinleibird  
       2023-08-12 19:27:26 +08:00
    改一下:

    题外话,你把视角代入到「执行栈」就容易想清楚了。(同步的执行栈如何管理异步代码?)
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2201 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 21ms UTC 00:20 PVG 08:20 LAX 16:20 JFK 19:20
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86