const taskQueue = {
high: [],
normal: [],
low: []
};
let isPerformingTask = false;
const channel = new MessageChannel();
const { port1, port2 } = channel;
port1.onmessage = () => {
performTask();
};
function performTask() {
for (let priority of ['high', 'normal', 'low']) {
if (taskQueue[priority].length > 0) {
isPerformingTask = true;
const task = taskQueue[priority].shift();
task();
isPerformingTask = false;
performTask();
return;
}
}
}
function scheduleTask(task, priority = 'normal') {
taskQueue[priority].push(task);
if (!isPerformingTask) {
port2.postMessage(null);
}
}
class FiberNode {
constructor(instance, lane) {
this.instance = instance;
this.props = instance.props;
this.child = null;
this.sibling = null;
this.return = null;
this.effectTag = null;
this.lane = lane;
}
}
let currentRootFiber = null;
const Lanes = {
HIGH: 1,
NORMAL: 2,
LOW: 3
};
class Component {
constructor(props) {
this.props = props;
this.state = {};
this._fiber = null;
}
setState(newState) {
this.state = Object.assign({}, this.state, newState);
scheduleTask(() => {
this._fiber = {
...this._fiber,
effectTag: 'UPDATE'
};
}, Lanes.NORMAL);
}
render() {}
}
function render(element, container) {
const fiber = new FiberNode({
type: element.type,
props: element.props
}, Lanes.NORMAL);
currentRootFiber = fiber;
scheduleTask(() => {
performWork(fiber);
}, Lanes.HIGH);
}
function performWork(fiber) {
if (!fiber.instance) {
return;
}
const children = fiber.instance.render();
reconcileChildren(fiber, children);
}
function reconcileChildren(parentFiber, children) {
let prevSibling = null;
let oldFiber = parentFiber.child;
for (let i = 0; i < children.length; i++) {
const child = children[i];
let newFiber = null;
if (oldFiber) {
} else {
}
if (i === 0) {
parentFiber.child = newFiber;
} else {
prevSibling.sibling = newFiber;
}
prevSibling = newFiber;
oldFiber = oldFiber ? oldFiber.sibling : null;
}
}
const rootElement = {
type: 'div',
props: {},
children: [
{type: 'p', props: {}, children: ['Hello, World!']}
]
};
render(rootElement, document.getElementById('root'));