diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts index a84b5c3d..7d6201a2 100644 --- a/libs/horizon/src/renderer/TreeBuilder.ts +++ b/libs/horizon/src/renderer/TreeBuilder.ts @@ -227,6 +227,8 @@ function buildVNodeTree(treeRoot: VNode) { } } while (true); + processing = null; + setExecuteMode(preMode); } @@ -272,7 +274,7 @@ export function launchUpdateFromVNode(vNode: VNode) { } // 保存待刷新的节点 - treeRoot.toUpdateNodes.add(vNode); + treeRoot.toUpdateNodes?.add(vNode); if (checkMode(BySync) && // 非批量 !checkMode(InRender)) { // 不是渲染阶段触发 diff --git a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts index 46260ac0..5e2fd84b 100644 --- a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts +++ b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts @@ -71,7 +71,7 @@ function callBeforeSubmitLifeCycles( const root = vNode.realNode; clearContainer(root.outerDom); } - + // No Default } } @@ -160,39 +160,26 @@ function hideOrUnhideAllChildren(vNode, isHidden) { function attachRef(vNode: VNode) { const ref = vNode.ref; - if (ref !== null) { - const instance = vNode.realNode; - - let refType = typeof ref; - if (refType === 'function') { - ref(instance); - } else if (refType === 'object') { - (ref).current = instance; - } else { - if (vNode.belongClassVNode && vNode.belongClassVNode.realNode) { - vNode.belongClassVNode.realNode.refs[String(ref)] = instance; - } - } - } + handleRef(vNode, ref, vNode.realNode); } function detachRef(vNode: VNode, isOldRef?: boolean) { let ref = (isOldRef ? vNode.oldRef : vNode.ref); - if (ref !== null) { - let refType = typeof ref; + handleRef(vNode, ref, null); +} + +function handleRef(vNode: VNode, ref, val) { + if (ref !== null && ref !== undefined) { + const refType = typeof ref; if (refType === 'function') { - try { - ref(null); - } catch (error) { - handleSubmitError(vNode, error); - } + ref(val); } else if (refType === 'object') { - (ref).current = null; + (ref).current = val; } else { if (vNode.belongClassVNode && vNode.belongClassVNode.realNode) { - vNode.belongClassVNode.realNode.refs[String(ref)] = null; + vNode.belongClassVNode.realNode.refs[String(ref)] = val; } } } diff --git a/libs/horizon/src/renderer/submit/Submit.ts b/libs/horizon/src/renderer/submit/Submit.ts index 774c7386..e76f0b97 100644 --- a/libs/horizon/src/renderer/submit/Submit.ts +++ b/libs/horizon/src/renderer/submit/Submit.ts @@ -35,13 +35,10 @@ let lastRoot: VNode | null = null; export function submitToRender(treeRoot) { treeRoot.shouldUpdate = treeRoot.childShouldUpdate; - - const startVNode = getStartVNode(); - // 置空task,让才能加入新的render任务 treeRoot.task = null; - setProcessing(null); + const startVNode = getStartVNode(); if (FlagUtils.hasAnyFlag(startVNode)) { // 把自己加上 diff --git a/libs/horizon/src/renderer/taskExecutor/BrowserAsync.ts b/libs/horizon/src/renderer/taskExecutor/BrowserAsync.ts index 185ec51d..4633625f 100644 --- a/libs/horizon/src/renderer/taskExecutor/BrowserAsync.ts +++ b/libs/horizon/src/renderer/taskExecutor/BrowserAsync.ts @@ -2,65 +2,45 @@ * 浏览器相关实现 */ -export let now; - -if (typeof performance === 'object' && typeof performance.now === 'function') { - const localPerformance = performance; - now = () => localPerformance.now(); -} else { - const localDate = Date; - const initialTime = localDate.now(); - now = () => localDate.now() - initialTime; -} - let isMessageLoopRunning = false; let browserCallback = null; -// 默认每次只运行5ms -const runTime = 5; -let deadline = 0; export function isOverTime() { - return now() >= deadline; + return false; } // 1、设置deadline;2、回调TaskExecutor传过来的browserCallback const callRenderTasks = () => { - if (browserCallback == null) { + if (browserCallback === null) { return; } - const currentTime = now(); - // 计算deadline - deadline = currentTime + runTime; try { // 执行callback - const hasMoreTask = browserCallback( - currentTime, - ); + const hasMoreTask = browserCallback(); if (!hasMoreTask) { // 没有更多task isMessageLoopRunning = false; browserCallback = null; } else { // 还有task,继续调用 - port.postMessage(null); + port2.postMessage(null); } } catch (error) { - port.postMessage(null); + port2.postMessage(null); throw error; } }; -const channel = new MessageChannel(); -const port = channel.port2; -channel.port1.onmessage = callRenderTasks; +const { port1, port2 } = new MessageChannel(); +port1.onmessage = callRenderTasks; export function requestBrowserCallback(callback) { browserCallback = callback; if (!isMessageLoopRunning) { isMessageLoopRunning = true; - port.postMessage(null); + port2.postMessage(null); } } diff --git a/libs/horizon/src/renderer/taskExecutor/RenderQueue.ts b/libs/horizon/src/renderer/taskExecutor/RenderQueue.ts index 125f0a17..0db72fcb 100644 --- a/libs/horizon/src/renderer/taskExecutor/RenderQueue.ts +++ b/libs/horizon/src/renderer/taskExecutor/RenderQueue.ts @@ -46,9 +46,7 @@ function callRenderQueue() { try { for (; i < renderQueue.length; i++) { let callback = renderQueue[i]; - do { - callback = callback(); - } while (callback !== null); + callback(); } renderQueue = null; } catch (error) { diff --git a/libs/horizon/src/renderer/taskExecutor/TaskExecutor.ts b/libs/horizon/src/renderer/taskExecutor/TaskExecutor.ts index f5a8b986..fa0a3294 100644 --- a/libs/horizon/src/renderer/taskExecutor/TaskExecutor.ts +++ b/libs/horizon/src/renderer/taskExecutor/TaskExecutor.ts @@ -5,10 +5,9 @@ import { requestBrowserCallback, isOverTime, - now, } from './BrowserAsync'; -import {add, shift, first} from './TaskQueue'; +import { add, shift, first, remove } from './TaskQueue'; const ImmediatePriority = 1; const NormalPriority = 10; @@ -16,89 +15,65 @@ const NormalPriority = 10; // 用于控制插入任务的顺序 let idCounter = 1; -let currentPriorityLevel = NormalPriority; - // 正在执行task let isProcessing = false; // 调度中,等待浏览器回调 -let isScheduling = false; - -function runSync(callback, priorityLevel = NormalPriority) { - const previousPriorityLevel = currentPriorityLevel; - currentPriorityLevel = priorityLevel; - - try { - return callback(); - } finally { - currentPriorityLevel = previousPriorityLevel; - } -} +let isWaiting = false; function runAsync(callback, priorityLevel= NormalPriority ) { - let timeout; + let increment; switch (priorityLevel) { case ImmediatePriority: - timeout = -1; + increment = -1; break; case NormalPriority: default: - timeout = 5000; + increment = 10000; break; } const task = { id: idCounter++, callback, - priorityLevel, - expirationTime: now() + timeout, + order: idCounter + increment, }; add(task); - if (!isScheduling && !isProcessing) { - isScheduling = true; + if (!isWaiting && !isProcessing) { + isWaiting = true; requestBrowserCallback(callTasks); } return task; } -function callTasks(initialTime) { - isScheduling = false; +function callTasks() { + isWaiting = false; isProcessing = true; let task = null; - const previousPriorityLevel = currentPriorityLevel; try { - let currentTime = initialTime; task = first(); // 循环执行task while (task !== null) { - if ( - task.expirationTime > currentTime && - isOverTime() - ) { - // 任务的过期时间大于当前时间(没达到此任务的过期时间)且超过了deadline + if (isOverTime()) { + // 超过了deadline break; } const callback = task.callback; - if (typeof callback === 'function') { + if (callback !== null) { task.callback = null; - currentPriorityLevel = task.priorityLevel; - const didUserCallbackTimeout = task.expirationTime <= currentTime; - const continuationCallback = callback(didUserCallbackTimeout); - currentTime = now(); - // 执行callback返回函数,重置callback - if (typeof continuationCallback === 'function') { - task.callback = continuationCallback; - } else { - if (task === first()) { - shift(); - } + callback(); + + if (task === first()) { + shift(); + } else { // 执行任务中可能插入了新任务 + remove(task); } } else { shift(); @@ -110,8 +85,6 @@ function callTasks(initialTime) { // 返回是否还有任务,如果有,说明是被中断了 return task !== null; } finally { - task = null; - currentPriorityLevel = previousPriorityLevel; isProcessing = false; } } @@ -120,16 +93,9 @@ function cancelTask(task) { task.callback = null; } -function getCurrentPriorityLevel() { - return currentPriorityLevel; -} - export { ImmediatePriority, NormalPriority, - runSync, runAsync, cancelTask, - getCurrentPriorityLevel, - now, }; diff --git a/libs/horizon/src/renderer/taskExecutor/TaskQueue.ts b/libs/horizon/src/renderer/taskExecutor/TaskQueue.ts index 708e9bdf..bfb98f79 100644 --- a/libs/horizon/src/renderer/taskExecutor/TaskQueue.ts +++ b/libs/horizon/src/renderer/taskExecutor/TaskQueue.ts @@ -5,7 +5,7 @@ type Queue = Array; type Node = { id: number; - expirationTime: number; + order: number; }; // 任务队列 @@ -15,9 +15,7 @@ export function add(node: Node): void { // 查找第一个大于等于 value 的下标,都比 value 小则返回 -1 const idx = getBiggerIdx(node); - if (idx === 0) { - taskQueue.unshift(node); - } else if (idx === -1) { + if (idx === -1) { taskQueue.push(node); } else { taskQueue.splice(idx, 0, node); @@ -32,10 +30,11 @@ function getBiggerIdx(node: Node) { while (left <= right) { const middle = left + ((right - left) >> 1); - if (compare(taskQueue[middle], node) > 0) + if (compare(taskQueue[middle], node) > 0) { right = middle - 1; - else + } else { left = middle + 1; + } } return (left < taskQueue.length) ? left : -1; @@ -51,8 +50,12 @@ export function shift(): Node | null { return val !== undefined ? val : null; } +export function remove(node: Node) { + taskQueue.splice(taskQueue.indexOf(node), 1); +} + function compare(a: Node, b: Node) { // 优先先用index排序,其次用id - const diff = a.expirationTime - b.expirationTime; + const diff = a.order - b.order; return diff !== 0 ? diff : a.id - b.id; }