<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          不用一行代碼,搞懂React調(diào)度器原理

          共 2346字,需瀏覽 5分鐘

           ·

          2021-12-29 16:15

          作者:卡頌

          簡(jiǎn)介:《React技術(shù)揭秘》作者

          來(lái)源:SegmentFault  思否社區(qū)


          大家好,我卡頌。


          Scheduler(調(diào)度器)是React重要的組成部分。


          Scheduler(調(diào)度器)地址:https://github.com/facebook/react/blob/main/packages/scheduler/src/forks/Scheduler.js


          同時(shí),他也是個(gè)獨(dú)立的包,任何連續(xù)、可中斷的流程都可以用Scheduler來(lái)調(diào)度,比如:


          const work = {count: 100};

          function doWork(work) {
            work.count--;
            console.log('do work!')
          }


          work滿足兩個(gè)條件:


          • 工作是連續(xù)的。一共需要執(zhí)行100次,每次執(zhí)行時(shí)調(diào)用doWork

          • 工作是可中斷的。中斷恢復(fù)后,接著中斷前的work.count繼續(xù)執(zhí)行就行


          滿足這兩個(gè)條件的工作都可以用Scheduler來(lái)調(diào)度。


          調(diào)度后,Scheduler內(nèi)部會(huì)生成對(duì)應(yīng)task,并在正確的時(shí)機(jī)執(zhí)行


          task.callback:

          const task1 = {
            // 過(guò)期時(shí)間 等于 當(dāng)前時(shí)間 + 優(yōu)先級(jí)對(duì)應(yīng)時(shí)間
            expirationTime: currentTime + priority,
            callback: doWork.bind(null, work)
          }


          本文會(huì)講解Scheduler的實(shí)現(xiàn)原理。知道你不喜歡看大段的代碼,所以本文沒(méi)有一行代碼。文末有Scheduler的源碼地址,感興趣的話可以去看看。


          開(kāi)整~


          前工作流程概覽



          Scheduler的工作原理如下圖,接下來(lái)會(huì)詳細(xì)解釋:



          Scheduler中有兩個(gè)容易混淆的概念:


          • delay


          delay代表task需要延遲執(zhí)行的時(shí)間。配置了delaytask會(huì)先進(jìn)入timerQueue中。


          當(dāng)delay對(duì)應(yīng)時(shí)間到期后,該task會(huì)轉(zhuǎn)移到taskQueue中。


          • expirationTime


          expirationTime代表task的過(guò)期時(shí)間


          不是所有task都會(huì)配置delay,沒(méi)有配置delaytask會(huì)直接進(jìn)入taskQueue。這就導(dǎo)致taskQueue中可能存在多個(gè)task


          如何決定哪個(gè)task.callback先執(zhí)行呢?Scheduler根據(jù)task.expirationTime作為排序依據(jù),值越小優(yōu)先級(jí)越高。


          如果task.expirationTime小于當(dāng)前時(shí)間,不僅優(yōu)先級(jí)最高,而且task.callback的執(zhí)行不會(huì)被中斷。


          總結(jié)一下task的幾種情況:


          1. 配置delaydelay未到期:task一定不會(huì)執(zhí)行
          2. 配置delay且到期,或者未配置delaytask,同時(shí)task.expirationTime未到期:根據(jù)task.expirationTime排序后,按順序執(zhí)行
          3. task.expirationTime到期的task:優(yōu)先級(jí)最高,且同步、不可中斷


          工作流程詳解



          將流程概覽圖替換為Scheduler中具體方法后,如下:


          完整工作流程如下:

          • 執(zhí)行Scheduler.scheduleCallback生成task


          根據(jù)是否傳遞delay參數(shù),生成的task會(huì)進(jìn)入timerQueuetaskQueue

          • 當(dāng)timerQueue中第一個(gè)task延遲的時(shí)間到期后,執(zhí)行advanceTimers到期的tasktimerQueue中移到taskQueue


          其中,timerQueue、taskQueue的數(shù)據(jù)結(jié)構(gòu)為小頂堆實(shí)現(xiàn)的優(yōu)先級(jí)隊(duì)列

          • 接下來(lái),執(zhí)行requestHostCallback方法,他會(huì)在新的宏任務(wù)中執(zhí)行workLoop方法


          宏任務(wù)中執(zhí)行回調(diào)的方法很多,Scheduler在瀏覽器環(huán)境默認(rèn)使用MessageChannel實(shí)現(xiàn)。

          如果不支持MessageChannel,會(huì)降級(jí)到setTimeoutNode老版IE下會(huì)使用setImmediate

          • workLoop方法會(huì)循環(huán)消費(fèi)taskQueue中的task(即執(zhí)行task.callback),直到滿足如下條件之一,中斷循環(huán):

          • taskQueue中不存在task

          • 時(shí)間切片用盡


          • 循環(huán)中斷后,如果taskQueue不為空,則進(jìn)入步驟3。如果timerQueue不為空,則進(jìn)入步驟2


          總結(jié)



          總結(jié)一下,Scheduler的完整執(zhí)行流程包括兩個(gè)循環(huán):

          • taskQueue的生產(chǎn)(從timerQueue中移入或執(zhí)行scheduleCallback生成)到消費(fèi)的過(guò)程(即圖中灰色部分),這是個(gè)異步循環(huán)。


          • taskQueue的具體消費(fèi)過(guò)程(即workLoop方法的執(zhí)行),這是個(gè)同步循環(huán)。


          如果你想了解React中如何使用Scheduler,可以參考100行代碼實(shí)現(xiàn)React核心調(diào)度功能



          點(diǎn)擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開(kāi)更多互動(dòng)和交流,掃描下方”二維碼“或在“公眾號(hào)后臺(tái)回復(fù)“ 入群 ”即可加入我們的技術(shù)交流群,收獲更多的技術(shù)文章~

          - END -


          瀏覽 22
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人三级电影天堂 | 欧美视频一区二区三区四区五区 | 国产小说一区二区三区 | 久草福利网 | 亚洲无码在线99 |