React源码学习之UpdateQueue(单链表)
2019-11-27 本文已影响0人
_楚轩
对UpdateQueue的产生和使用有所疑问,所以模拟一下。
// 创建一个更新
function createUpdate(expirationTime) {
return {
expirationTime: expirationTime,
tag: 0,
payload: null,
callback: null,
next: null,
nextEffect: null,
};
}
// 创建一个包含各个Update的单向链表
function createUpdateQueue(baseState) {
const queue = {
baseState,
firstUpdate: null,
lastUpdate: null,
firstCapturedUpdate: null,
lastCapturedUpdate: null,
firstEffect: null,
lastEffect: null,
firstCapturedEffect: null,
lastCapturedEffect: null,
};
return queue;
}
// 添加 update对象 到 单向链表中
function appendUpdateToQueue(
queue,update
) {
// Append the update to the end of the list.
if (queue.lastUpdate === null) {
// Queue is empty
// firstUpdate和lastUpdate都保存的是 update这个对象的引用
queue.firstUpdate = queue.lastUpdate = update;
} else {·
// 当firstUpdate和lastUpdate相同的情况下,修改lastUpdate的next值其实就是修改了firstUpdate的next值。在取值的时候也是一直从firstUpdate取next,取到最后一个节点为止。
queue.lastUpdate.next = update;
// 然后queue的lastUpadate就指向这个新的update
queue.lastUpdate = update;
}
}
下面模拟一下Update创建并且加入到单向链表UpdateQueue中,首先创建一个UpdateQueue。
var queue = createUpdateQueue({})
创建三个Update
var update1 = createUpdate(1)
var update2 = createUpdate(2)
var update3 = createUpdate(3)
依次连接起来
appendUpdateToQueue(queue, update1)
appendUpdateToQueue(queue, update2)
appendUpdateToQueue(queue, update3)
看一下queue
console.log('qeueu', queue)
从fitstUpdate开始,以next连接每一个Update
queue
需要调用的时候就这样做,下例是打出链表所有的nextNodeExpirationTime
function LoopQueue () {
let firstUpdate = queue.firstUpdate
if (!firstUpdate ) {
console.error('该链表为空')
return
}
let currentNode = firstUpdate
console.log('nextNodeExpirationTime', firstUpdate .expirationTime)
while (currentNode.next){
let nextNode = currentNode.next
console.log('nextNodeExpirationTime', nextNode.expirationTime)
currentNode = currentNode.next
}
}
LoopQueue()