
import elements from './element.js'// 目的: 把虚拟DOM渲染到根节点中let container = document.getElementById('root');const PLACEMENT = 'PLACEMENT';// 下一个工作单元// fiber对象其实也是一个普通的JS对象let workInProgressRoot = { stateNode: container, // 静态节点,fiber的真实DOM props: {children: [elements]}, // fiber的属性};let nextUnitOfWork = workInProgressRoot;function workLoop(){ while(nextUnitOfWork){ // 下一个工作单元 nextUnitOfWork = performUnitOfWork(nextUnitOfWork) // 返回下一个工作单元 } if(!nextUnitOfWork){ commitRoot() }}function commitRoot () { let currentFiber = workInProgressRoot.firstEffect; while(currentFiber){ if(currentFiber.effectTag === PLACEMENT){ console.log('commitRoot',currentFiber.return.stateNode) console.log('currentFiber.stateNode',currentFiber.stateNode) currentFiber.return.stateNode.appendChild(currentFiber.stateNode) } currentFiber = currentFiber.nextEffect; } workInProgressRoot = null;}function performUnitOfWork (workingInProgressFiber) { // workingInProgressFiber 正在工作中的fiber节点 beginWork(workingInProgressFiber) // 创建真实DOM 创建fiber子节点, 不进行挂载 if(workingInProgressFiber.child){ // 如果有子节点就返回 return workingInProgressFiber.child } while(workingInProgressFiber){ completeUnitOfWork(workingInProgressFiber) if(workingInProgressFiber.sibling){ // 如果有兄弟节点就返回 return workingInProgressFiber.sibling } workingInProgressFiber = workingInProgressFiber.return // 如果都没有 指向父节点 重新寻找 }}function beginWork (workingInProgressFiber){ console.log('beginWork', workingInProgressFiber.props.id) // 创建真实DOM if(!workingInProgressFiber.stateNode){ workingInProgressFiber.stateNode = document.createElement(workingInProgressFiber.type) for(let key in workingInProgressFiber.props){ if(key !== 'children'){ workingInProgressFiber.stateNode[key] = workingInProgressFiber.props[key]; } } } // 创建子fiber let perviousFiber; if(Array.isArray(workingInProgressFiber.props.children)){ workingInProgressFiber.props.children.forEach((child, index) =>{ let childFiber ={ type: child.type, props: child.props, return: workingInProgressFiber, // effectTag: PLACEMENT, // 副作用标记,表示这个节点要进行什么操作 nextEffect: null // 下一个有副作用的节点 } if(index === 0) { workingInProgressFiber.child = childFiber // 让父节点的child指向儿子 } else { perviousFiber.sibling = childFiber; } perviousFiber = childFiber }) }} function completeUnitOfWork (workingInProgressFiber) { console.log('completeUnitOfWork', workingInProgressFiber.props.id) // 构建副作用链,effectList,只有那些有副作用的节点 let returnFiber = workingInProgressFiber.return; // A1 if(returnFiber){ // 把子的副作用和自己的副作用都归到自己身上 // 把当前fiber的有副作用子链表挂载到父亲身上 if(!returnFiber.firstEffect){ returnFiber.firstEffect = workingInProgressFiber.firstEffect } if(workingInProgressFiber.lastEffect){ if(returnFiber.lastEffect){ returnFiber.lastEffect.nextEffect = workingInProgressFiber.firstEffect } returnFiber.lastEffect = workingInProgressFiber.lastEffect; } // 再把自己挂到后边 if(workingInProgressFiber.effectTag){ if(returnFiber.lastEffect){ returnFiber.lastEffect.nextEffect = workingInProgressFiber; } else { returnFiber.firstEffect = workingInProgressFiber } returnFiber.lastEffect = workingInProgressFiber; } }}// 告诉浏览器在每帧的空余时间调用工作循环requestIdleCallback(workLoop)