0
点赞
收藏
分享

微信扫一扫

React 环状链表

凉夜lrs 2022-01-15 阅读 33

1. React中的链表

React Fiber版本的源码中使用到链表的数据结构(为了实现低优先级任务的暂停与重启),包括单向链表和环状链表。

  • 首先,Hooks是以单向链表的形式存储在 Fiber 的 memoizedState 属性身上

  •  同时,每个hooks又拥有自己的更新队列queue,queue.pending 会指向一个环状链表

2. 单向链表代码实现

function buildQueue(queue,action){
    const update = {action,next:null}
    const pending = queue.pending

    if(!pending){
        queue.pending = update
    }else{
        let current = queue.pending
        // 找到末尾的元素
        while(current.next){
            current = current.next
        }
        // 将update挂载到链表的末尾
        current.next = update
    }
}

// excute
let queue = {pending:null}
buildQueue(queue,'hooks1')
buildQueue(queue,'hooks2')

// output: queue.pending = {action:'hooks1',next:{action:'hooks2',next:null}}

3. 环状链表代码实现

function dispatchAction(queue,action){
     const update = {action,next:null}
     const pending = queue.pending
     if(pending === null){
        update.next = update // 自己与自己创建一个环状链表
     }else{
        update.next = pending.next
        pending.next = update
     }
     queue.pending = update
}

let queue = {pending:null}

/**
 * update.next === update
 * queue.pending === update(action) 
 */
dispatchAction(queue,'action')


/**
 * update(action1).next -> update(action).next [update(action)]    
 * update1 的next 指向 update

 * queue.pending.next [update(update)] -> update(action1)          
 * update 指向 update1

 * queue.pending -> update(action1)                                
 * queue.pending 指向 update1
 */
dispatchAction(queue,'action1')

  •  由图可知,queue.pending 永远指向最后一个更新
  •  由图可知,pending.next 永远指向第一个更新

4. 结语

栈,堆,队列,链表,树等数据结构我们平时写代码也许体会不到用处,但在学习框架源码的时候,我们可以体会到数据结构的妙处(虚拟dom与diff算法是对二叉树的应用与遍历,hooks的更新队列是循环链表),加深我们对数据的理解,提升我们的逻辑思维。

举报

相关推荐

0 条评论