29. React源碼之更新優(yōu)先級(jí)--lane

更新可以設(shè)置優(yōu)先級(jí),在處理更新的時(shí)候可以指定渲染優(yōu)先級(jí)贾虽,高于指定渲染優(yōu)先級(jí)的更新才能渲染埠胖。React中使用lane(車道)表示任務(wù)優(yōu)先級(jí),共有31個(gè)lane攒盈,數(shù)字越小優(yōu)先級(jí)越高,有些lane優(yōu)先級(jí)相同哎榴。

代碼詳情

const NoLanes = 0b00;
const NoLane = 0b00;
const SyncLane = 0b01;
const InputContinuousHydrationLane = 0b10;
function isSubsetOfLanes(set, subset) {
  return (set & subset) === subset;
}
function mergeLanes(a, b) {
  return a | b;
}
function initializeUpdateQueue(fiber) {
  const queue = {
    baseState: fiber.memoizedState,
    firstBaseUpdate: null,
    lastBaseUpdate: null,
    shared: {
      pending: null,
    },
  };
  fiber.updateQueue = queue;
}
function enqueueUpdate(fiber, update) {
  const updateQueue = fiber.updateQueue;
  const sharedQueue = updateQueue.shared;
  const pending = sharedQueue.pending;
  if (pending === null) {
    update.next = update;
  } else {
    update.next = pending.next;
    pending.next = update;
  }
  sharedQueue.pending = update;
}
function processUpdateQueue(fiber, renderLanes) {
  const queue = fiber.updateQueue;
  let firstBaseUpdate = queue.firstBaseUpdate;
  let lastBaseUpdate = queue.lastBaseUpdate;
  const pendingQueue = queue.shared.pending;
  if (pendingQueue !== null) {
    queue.shared.pending = null;
    const lastPendingUpdate = pendingQueue;
    const firstPendingUpdate = lastPendingUpdate.next;
    lastPendingUpdate.next = null;
    if (lastBaseUpdate === null) {
      firstBaseUpdate = firstPendingUpdate;
    } else {
      lastBaseUpdate.next = firstPendingUpdate;
    }
    lastBaseUpdate = lastPendingUpdate;
  }
  if (firstBaseUpdate !== null) {
    let newState = queue.baseState;
    let newLanes = NoLanes;
    let newBaseState = null;
    let newFirstBaseUpdate = null;
    let newLastBaseUpdate = null;
    let update = firstBaseUpdate;
    do {
      const updateLane = update.lane;
      if (updateLane > renderLanes) {
        const clone = {
          id: update.id,
          lane: updateLane,
          payload: update.payload,
        };
        if (newLastBaseUpdate === null) {
          newFirstBaseUpdate = newLastBaseUpdate = clone;
          newBaseState = newState;
        } else {
          newLastBaseUpdate = newLastBaseUpdate.next = clone;
        }
        newLanes = mergeLanes(newLanes, updateLane);
      } else {
        if (newLastBaseUpdate !== null) {
          const clone = {
            id: update.id,
            lane: NoLane,
            payload: update.payload,
          };
          newLastBaseUpdate = newLastBaseUpdate.next = clone;
        }
        newState = getStateFromUpdate(update, newState);
      }
      update = update.next;
    } while (update);
    if (!newLastBaseUpdate) {
      newBaseState = newState;
    }
    queue.baseState = newBaseState;
    queue.firstBaseUpdate = newFirstBaseUpdate;
    queue.lastBaseUpdate = newLastBaseUpdate;
    fiber.lanes = newLanes;
    fiber.memoizedState = newState;
  }
}
function getStateFromUpdate(update, prevState) {
  return update.payload(prevState);
}
let fiber = {
  memoizedState: "",
};
initializeUpdateQueue(fiber);
let updateA = {
  id: "A",
  payload: (state) => state + "A",
  lane: SyncLane,
};
enqueueUpdate(fiber, updateA);
let updateB = {
  id: "B",
  payload: (state) => state + "B",
  lane: InputContinuousHydrationLane,
};
enqueueUpdate(fiber, updateB);
let updateC = {
  id: "C",
  payload: (state) => state + "C",
  lane: SyncLane,
};
enqueueUpdate(fiber, updateC);
let updateD = {
  id: "D",
  payload: (state) => state + "D",
  lane: SyncLane,
};
enqueueUpdate(fiber, updateD);
processUpdateQueue(fiber, SyncLane);
console.log(fiber.memoizedState);
console.log("updateQueue", printUpdateQueue(fiber.updateQueue));
let updateE = {
  id: "E",
  payload: (state) => state + "E",
  lane: InputContinuousHydrationLane,
};
enqueueUpdate(fiber, updateE);
let updateF = {
  id: "F",
  payload: (state) => state + "F",
  lane: SyncLane,
};
enqueueUpdate(fiber, updateF);
processUpdateQueue(fiber, InputContinuousHydrationLane);
console.log(fiber.memoizedState);
console.log("updateQueue", printUpdateQueue(fiber.updateQueue));
function printUpdateQueue(updateQueue) {
  const { baseState, firstBaseUpdate } = updateQueue;
  let desc = baseState + "#";
  let update = firstBaseUpdate;
  while (update) {
    desc += update.id + "=>";
    update = update.next;
  }
  desc += "null";
  return desc;
}
// 渲染結(jié)果
// ACD
// updateQueue A#B=>C=>D=>null
// ABCDEF
// updateQueue ABCDEF#null
updateQueue.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末型豁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子尚蝌,更是在濱河造成了極大的恐慌迎变,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件飘言,死亡現(xiàn)場(chǎng)離奇詭異衣形,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)姿鸿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門谆吴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人苛预,你說我怎么就攤上這事句狼。” “怎么了热某?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵腻菇,是天一觀的道長胳螟。 經(jīng)常有香客問我,道長筹吐,這世上最難降的妖魔是什么糖耸? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮骏令,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘垄提。我一直安慰自己榔袋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布铡俐。 她就那樣靜靜地躺著凰兑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪审丘。 梳的紋絲不亂的頭發(fā)上吏够,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音滩报,去河邊找鬼锅知。 笑死,一個(gè)胖子當(dāng)著我的面吹牛脓钾,可吹牛的內(nèi)容都是我干的售睹。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼可训,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼昌妹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起握截,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤飞崖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后谨胞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體固歪,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年胯努,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了昼牛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡康聂,死狀恐怖贰健,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情恬汁,我是刑警寧澤伶椿,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布辜伟,位于F島的核電站,受9級(jí)特大地震影響脊另,放射性物質(zhì)發(fā)生泄漏导狡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一偎痛、第九天 我趴在偏房一處隱蔽的房頂上張望旱捧。 院中可真熱鬧,春花似錦踩麦、人聲如沸枚赡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贫橙。三九已至,卻和暖如春反粥,著一層夾襖步出監(jiān)牢的瞬間卢肃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國打工才顿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留莫湘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓郑气,卻偏偏與公主長得像逊脯,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子竣贪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容