日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

一圖看懂 React 源碼中的同步更新邏輯

來(lái)源: 責(zé)編: 時(shí)間:2024-05-11 09:21:16 290觀看
導(dǎo)讀在 React 源碼中,scheduleUpdateOnFiber 是所有任務(wù)的唯一入口方法。我們前面分析 useState 的實(shí)現(xiàn)原理章節(jié)中,我們可以清晰的知道,當(dāng)我們調(diào)用 dispatchSetState 時(shí),最終會(huì)調(diào)用該入口方法。scheduleUpdateOnFiber 主要用

O1028資訊網(wǎng)——每日最新資訊28at.com

在 React 源碼中,scheduleUpdateOnFiber 是所有任務(wù)的唯一入口方法。我們前面分析 useState 的實(shí)現(xiàn)原理章節(jié)中,我們可以清晰的知道,當(dāng)我們調(diào)用 dispatchSetState 時(shí),最終會(huì)調(diào)用該入口方法。O1028資訊網(wǎng)——每日最新資訊28at.com

O1028資訊網(wǎng)——每日最新資訊28at.com

scheduleUpdateOnFiber 主要用于觸發(fā)一個(gè) Fiber 節(jié)點(diǎn)上的調(diào)度更新任務(wù),該函數(shù)里主要有兩個(gè)核心邏輯。O1028資訊網(wǎng)——每日最新資訊28at.com

// Mark that the root has a pending update.// 標(biāo)記 root 上有一個(gè)更新任務(wù)markRootUpdated(root, lane, eventTime);ensureRootIsScheduled(root, eventTime);

markRootUpdated 的邏輯如下,簡(jiǎn)單了解一下即可。O1028資訊網(wǎng)——每日最新資訊28at.com

export function markRootUpdated(  root: FiberRoot,  updateLane: Lane,  eventTime: number,) {  // 設(shè)置本次更新的優(yōu)先級(jí)  root.pendingLanes |= updateLane;  // 重置 root 應(yīng)用根節(jié)點(diǎn)的優(yōu)先級(jí)  if (updateLane !== IdleLane) {      // 由 Suspence 而掛起的 update 對(duì)應(yīng)的 lane 集合    root.suspendedLanes = NoLanes;     // 由請(qǐng)求成功,Suspence 取消掛起的 update 對(duì)應(yīng)的 Lane 集合    root.pingedLanes = NoLanes;   }  const eventTimes = root.eventTimes;  const index = laneToIndex(updateLane);  eventTimes[index] = eventTime;}

ensureRootIsScheduled 的主要目的要確保 root 根節(jié)點(diǎn)被調(diào)度。在該邏輯中,會(huì)根據(jù) root.pendingLanes 信息計(jì)算出本次更新的 Lanes: nextLanes。O1028資訊網(wǎng)——每日最新資訊28at.com

const nextLanes = getNextLanes(  root,  root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,);

然后根據(jù) nextLanes 計(jì)算出本批次集合中優(yōu)先級(jí)最高的 Lane,作為本地任務(wù)的優(yōu)先級(jí)。O1028資訊網(wǎng)——每日最新資訊28at.com

// We use the highest priority lane to represent the priority of the callback.const newCallbackPriority = getHighestPriorityLane(nextLanes);

后續(xù)的邏輯就是取出當(dāng)前已存在的調(diào)度優(yōu)先級(jí),與 newCallbackPriority 進(jìn)行對(duì)比,根據(jù)對(duì)比結(jié)果來(lái)執(zhí)行不同的更新方法。當(dāng)該值等于 SyncLane 時(shí),表示為同步更新。O1028資訊網(wǎng)——每日最新資訊28at.com

同步優(yōu)先級(jí)例如點(diǎn)擊事件。O1028資訊網(wǎng)——每日最新資訊28at.com

然后會(huì)判斷是否支持微任務(wù)更新,如果不支持最后會(huì)執(zhí)行 scheduleCallback。O1028資訊網(wǎng)——每日最新資訊28at.com

if (newCallbackPriority === SyncLane) {  if (supportsMicrotasks) {    // Flush the queue in a microtask.    if (__DEV__ && ReactCurrentActQueue.current !== null) {      // Inside `act`, use our internal `act` queue so that these get flushed      // at the end of the current scope even when using the sync version      // of `act`.      ReactCurrentActQueue.current.push(flushSyncCallbacks);    } else {      scheduleMicrotask(() => {        // In Safari, appending an iframe forces microtasks to run.        // https://github.com/facebook/react/issues/22459        // We don't support running callbacks in the middle of render        // or commit so we need to check against that.        if (          (executionContext & (RenderContext | CommitContext)) ===          NoContext        ) {          // Note that this would still prematurely flush the callbacks          // if this happens outside render or commit phase (e.g. in an event).          flushSyncCallbacks();        }      });    }  } else {    // Flush the queue in an Immediate task.    scheduleCallback(ImmediateSchedulerPriority, flushSyncCallbacks);  }}

scheduleSyncCallback 的邏輯,也就是同步任務(wù)的調(diào)度非常簡(jiǎn)單,就是將執(zhí)行同步任務(wù)的回調(diào)添加到一個(gè)同步隊(duì)列 syncQueue 中。O1028資訊網(wǎng)——每日最新資訊28at.com

export function scheduleSyncCallback(callback: SchedulerCallback) {  // Push this callback into an internal queue. We'll flush these either in  // the next tick, or earlier if something calls `flushSyncCallbackQueue`.  if (syncQueue === null) {    syncQueue = [callback];  } else {    // Push onto existing queue. Don't need to schedule a callback because    // we already scheduled one when we created the queue.    syncQueue.push(callback);  }}

這里的 callback 是之前傳入的 performSyncWorkOnRoot,這是用來(lái)執(zhí)行同步更新任務(wù)的方法。他的邏輯主要包括:O1028資訊網(wǎng)——每日最新資訊28at.com

  • 調(diào)用 renderRootSync,該方法會(huì)執(zhí)行 workLoopSync,最后生成 Fiber true。
  • 將創(chuàng)建完成的 Fiber tree 掛載到 root 節(jié)點(diǎn)上。
  • 最后調(diào)用 commitRoot,進(jìn)入 commit 階段修改真實(shí) DOM。
function performSyncWorkOnRoot(root) {  ...  let exitStatus = renderRootSync(root, lanes);    ...  root.finishedWork = finishedWork;  root.finishedLanes = lanes;  commitRoot(    root,    workInProgressRootRecoverableErrors,    workInProgressTransitions,  );  ensureRootIsScheduled(root, now());  return null;}

workLoopSync 的邏輯也非常簡(jiǎn)單,如下:O1028資訊網(wǎng)——每日最新資訊28at.com

function workLoopSync() {  // Already timed out, so perform work without checking if we need to yield.  while (workInProgress !== null) {    performUnitOfWork(workInProgress);  }}

在 performUnitOfWork 中,會(huì)調(diào)用 beginWork 方法開(kāi)始創(chuàng)建 Fiber 節(jié)點(diǎn)。O1028資訊網(wǎng)——每日最新資訊28at.com

var next = beginWork(  current,   unitOfWork,   subtreeRenderLanes);

總結(jié)

同步更新的過(guò)程比較簡(jiǎn)單,從 scheduleUpdateOnFiber 到 beginWork 這中間的流程里,大多數(shù)邏輯都在進(jìn)行各種不同情況的判斷,因此源碼看上去比較吃力,實(shí)際邏輯并不是很重要,簡(jiǎn)單了解即可,重要的是 beginWork 創(chuàng)建 Fiber 節(jié)點(diǎn)的方法,這跟我們之前文章里提到過(guò)的優(yōu)化策略是一致的。O1028資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-87990-0.html一圖看懂 React 源碼中的同步更新邏輯

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 一篇學(xué)會(huì)Go中reflect反射的詳細(xì)用法

下一篇: SpringBoot3使用虛擬線程一定要小心了

標(biāo)簽:
  • 熱門(mén)焦點(diǎn)
  • 6月iOS設(shè)備性能榜:M2穩(wěn)居榜首 A系列只能等一手3nm來(lái)救

    沒(méi)有新品發(fā)布,自然iOS設(shè)備性能榜的上榜設(shè)備就沒(méi)有什么更替,僅僅只有跑分變化而產(chǎn)生的排名變動(dòng),畢竟蘋(píng)果新品的發(fā)布節(jié)奏就是這樣的,一年下來(lái)也就幾個(gè)移動(dòng)端新品,不會(huì)像安卓廠商,一
  • Rust中的高吞吐量流處理

    作者 | Noz編譯 | 王瑞平本篇文章主要介紹了Rust中流處理的概念、方法和優(yōu)化。作者不僅介紹了流處理的基本概念以及Rust中常用的流處理庫(kù),還使用這些庫(kù)實(shí)現(xiàn)了一個(gè)流處理程序
  • 一文掌握 Golang 模糊測(cè)試(Fuzz Testing)

    模糊測(cè)試(Fuzz Testing)模糊測(cè)試(Fuzz Testing)是通過(guò)向目標(biāo)系統(tǒng)提供非預(yù)期的輸入并監(jiān)視異常結(jié)果來(lái)發(fā)現(xiàn)軟件漏洞的方法。可以用來(lái)發(fā)現(xiàn)應(yīng)用程序、操作系統(tǒng)和網(wǎng)絡(luò)協(xié)議等中的漏洞或
  • 雅柏威士忌多款單品價(jià)格大跌,泥煤頂流也不香了?

    來(lái)源 | 烈酒商業(yè)觀察編 | 肖海林今年以來(lái),威士忌市場(chǎng)開(kāi)始出現(xiàn)了降溫跡象,越來(lái)越多不斷暴漲的網(wǎng)紅威士忌也開(kāi)始悄然回歸市場(chǎng)理性。近日,LVMH集團(tuán)旗下蘇格蘭威士忌品牌雅柏(Ardbeg
  • 得物寵物生意「狂飆」,發(fā)力“它經(jīng)濟(jì)”

    作者|花花小萌主近日,得物宣布正式上線寵物鑒別,通過(guò)得物App內(nèi)的“在線鑒別”,可找到鑒別寵物的選項(xiàng)。通過(guò)上傳自家寵物的部位細(xì)節(jié),就能收獲擁有專(zhuān)業(yè)資質(zhì)認(rèn)證的得物鑒
  • iQOO 11S或7月上市:搭載“雞血版”驍龍8Gen2 史上最強(qiáng)5G Soc

    去年底,iQOO推出了“電競(jìng)旗艦”iQOO 11系列,作為一款性能強(qiáng)機(jī),iQOO 11不僅全球首發(fā)2K 144Hz E6全感屏,搭載了第二代驍龍8平臺(tái)及144Hz電競(jìng)屏,同時(shí)在快充
  • iQOO Neo8 Pro搶先上架:首發(fā)天璣9200+ 安卓性能之王

    經(jīng)過(guò)了一段時(shí)間的密集爆料,昨日iQOO官方如期對(duì)外宣布:將于5月23日推出全新的iQOO Neo8系列新品,官方稱(chēng)這是一款擁有旗艦級(jí)性能調(diào)校的作品。隨著發(fā)布時(shí)
  • 蘋(píng)果MacBook Pro 2021測(cè)試:仍不支持平滑滾動(dòng)

    據(jù)10月30日9to5 Mac 消息報(bào)道,蘋(píng)果新的 14 英寸和 16 英寸 MacBook Pro 2021 上市后獲得了不錯(cuò)的評(píng)價(jià),亮點(diǎn)包括行業(yè)領(lǐng)先的性能,令人印象深刻的電池續(xù)航,精美豐
  • 北京:科技教育體驗(yàn)基地開(kāi)始登記

      北京“科技館之城”科技教育體驗(yàn)基地登記和認(rèn)證工作日前啟動(dòng)。首批北京科技教育體驗(yàn)基地?cái)M于2023年全國(guó)科普日期間掛牌,后續(xù)還將開(kāi)展常態(tài)化登記。  北京科技教育體驗(yàn)基
Top 主站蜘蛛池模板: 清原| 元阳县| 高陵县| 德令哈市| 石景山区| 诸暨市| 平顶山市| 沙田区| 陕西省| 新民市| 宜州市| 杂多县| 永吉县| 富顺县| 浦北县| 汉源县| 察隅县| 藁城市| 宜章县| 金寨县| 盱眙县| 泗水县| 博兴县| 万盛区| 施秉县| 泾阳县| 秦皇岛市| 遂昌县| 志丹县| 托里县| 邵阳县| 通城县| 海盐县| 清水县| 抚州市| 丰原市| 织金县| 唐海县| 乌拉特中旗| 泽州县| 扬州市|