Match-id-6e2cdb6edac0f6149760a50d07e710180a3f70b9

This commit is contained in:
* 2022-01-22 16:03:31 +08:00 committed by *
commit 89c90b001e
7 changed files with 53 additions and 120 deletions

View File

@ -227,6 +227,8 @@ function buildVNodeTree(treeRoot: VNode) {
} }
} while (true); } while (true);
processing = null;
setExecuteMode(preMode); setExecuteMode(preMode);
} }
@ -272,7 +274,7 @@ export function launchUpdateFromVNode(vNode: VNode) {
} }
// 保存待刷新的节点 // 保存待刷新的节点
treeRoot.toUpdateNodes.add(vNode); treeRoot.toUpdateNodes?.add(vNode);
if (checkMode(BySync) && // 非批量 if (checkMode(BySync) && // 非批量
!checkMode(InRender)) { // 不是渲染阶段触发 !checkMode(InRender)) { // 不是渲染阶段触发

View File

@ -71,7 +71,7 @@ function callBeforeSubmitLifeCycles(
const root = vNode.realNode; const root = vNode.realNode;
clearContainer(root.outerDom); clearContainer(root.outerDom);
} }
// No Default // No Default
} }
} }
@ -160,39 +160,26 @@ function hideOrUnhideAllChildren(vNode, isHidden) {
function attachRef(vNode: VNode) { function attachRef(vNode: VNode) {
const ref = vNode.ref; const ref = vNode.ref;
if (ref !== null) { handleRef(vNode, ref, vNode.realNode);
const instance = vNode.realNode;
let refType = typeof ref;
if (refType === 'function') {
ref(instance);
} else if (refType === 'object') {
(<RefType>ref).current = instance;
} else {
if (vNode.belongClassVNode && vNode.belongClassVNode.realNode) {
vNode.belongClassVNode.realNode.refs[String(ref)] = instance;
}
}
}
} }
function detachRef(vNode: VNode, isOldRef?: boolean) { function detachRef(vNode: VNode, isOldRef?: boolean) {
let ref = (isOldRef ? vNode.oldRef : vNode.ref); let ref = (isOldRef ? vNode.oldRef : vNode.ref);
if (ref !== null) { handleRef(vNode, ref, null);
let refType = typeof ref; }
function handleRef(vNode: VNode, ref, val) {
if (ref !== null && ref !== undefined) {
const refType = typeof ref;
if (refType === 'function') { if (refType === 'function') {
try { ref(val);
ref(null);
} catch (error) {
handleSubmitError(vNode, error);
}
} else if (refType === 'object') { } else if (refType === 'object') {
(<RefType>ref).current = null; (<RefType>ref).current = val;
} else { } else {
if (vNode.belongClassVNode && vNode.belongClassVNode.realNode) { if (vNode.belongClassVNode && vNode.belongClassVNode.realNode) {
vNode.belongClassVNode.realNode.refs[String(ref)] = null; vNode.belongClassVNode.realNode.refs[String(ref)] = val;
} }
} }
} }

View File

@ -35,13 +35,10 @@ let lastRoot: VNode | null = null;
export function submitToRender(treeRoot) { export function submitToRender(treeRoot) {
treeRoot.shouldUpdate = treeRoot.childShouldUpdate; treeRoot.shouldUpdate = treeRoot.childShouldUpdate;
const startVNode = getStartVNode();
// 置空task让才能加入新的render任务 // 置空task让才能加入新的render任务
treeRoot.task = null; treeRoot.task = null;
setProcessing(null); const startVNode = getStartVNode();
if (FlagUtils.hasAnyFlag(startVNode)) { if (FlagUtils.hasAnyFlag(startVNode)) {
// 把自己加上 // 把自己加上

View File

@ -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 isMessageLoopRunning = false;
let browserCallback = null; let browserCallback = null;
// 默认每次只运行5ms
const runTime = 5;
let deadline = 0;
export function isOverTime() { export function isOverTime() {
return now() >= deadline; return false;
} }
// 1、设置deadline2、回调TaskExecutor传过来的browserCallback // 1、设置deadline2、回调TaskExecutor传过来的browserCallback
const callRenderTasks = () => { const callRenderTasks = () => {
if (browserCallback == null) { if (browserCallback === null) {
return; return;
} }
const currentTime = now();
// 计算deadline
deadline = currentTime + runTime;
try { try {
// 执行callback // 执行callback
const hasMoreTask = browserCallback( const hasMoreTask = browserCallback();
currentTime,
);
if (!hasMoreTask) { // 没有更多task if (!hasMoreTask) { // 没有更多task
isMessageLoopRunning = false; isMessageLoopRunning = false;
browserCallback = null; browserCallback = null;
} else { } else {
// 还有task继续调用 // 还有task继续调用
port.postMessage(null); port2.postMessage(null);
} }
} catch (error) { } catch (error) {
port.postMessage(null); port2.postMessage(null);
throw error; throw error;
} }
}; };
const channel = new MessageChannel(); const { port1, port2 } = new MessageChannel();
const port = channel.port2; port1.onmessage = callRenderTasks;
channel.port1.onmessage = callRenderTasks;
export function requestBrowserCallback(callback) { export function requestBrowserCallback(callback) {
browserCallback = callback; browserCallback = callback;
if (!isMessageLoopRunning) { if (!isMessageLoopRunning) {
isMessageLoopRunning = true; isMessageLoopRunning = true;
port.postMessage(null); port2.postMessage(null);
} }
} }

View File

@ -46,9 +46,7 @@ function callRenderQueue() {
try { try {
for (; i < renderQueue.length; i++) { for (; i < renderQueue.length; i++) {
let callback = renderQueue[i]; let callback = renderQueue[i];
do { callback();
callback = callback();
} while (callback !== null);
} }
renderQueue = null; renderQueue = null;
} catch (error) { } catch (error) {

View File

@ -5,10 +5,9 @@
import { import {
requestBrowserCallback, requestBrowserCallback,
isOverTime, isOverTime,
now,
} from './BrowserAsync'; } from './BrowserAsync';
import {add, shift, first} from './TaskQueue'; import { add, shift, first, remove } from './TaskQueue';
const ImmediatePriority = 1; const ImmediatePriority = 1;
const NormalPriority = 10; const NormalPriority = 10;
@ -16,89 +15,65 @@ const NormalPriority = 10;
// 用于控制插入任务的顺序 // 用于控制插入任务的顺序
let idCounter = 1; let idCounter = 1;
let currentPriorityLevel = NormalPriority;
// 正在执行task // 正在执行task
let isProcessing = false; let isProcessing = false;
// 调度中,等待浏览器回调 // 调度中,等待浏览器回调
let isScheduling = false; let isWaiting = false;
function runSync(callback, priorityLevel = NormalPriority) {
const previousPriorityLevel = currentPriorityLevel;
currentPriorityLevel = priorityLevel;
try {
return callback();
} finally {
currentPriorityLevel = previousPriorityLevel;
}
}
function runAsync(callback, priorityLevel= NormalPriority ) { function runAsync(callback, priorityLevel= NormalPriority ) {
let timeout; let increment;
switch (priorityLevel) { switch (priorityLevel) {
case ImmediatePriority: case ImmediatePriority:
timeout = -1; increment = -1;
break; break;
case NormalPriority: case NormalPriority:
default: default:
timeout = 5000; increment = 10000;
break; break;
} }
const task = { const task = {
id: idCounter++, id: idCounter++,
callback, callback,
priorityLevel, order: idCounter + increment,
expirationTime: now() + timeout,
}; };
add(task); add(task);
if (!isScheduling && !isProcessing) { if (!isWaiting && !isProcessing) {
isScheduling = true; isWaiting = true;
requestBrowserCallback(callTasks); requestBrowserCallback(callTasks);
} }
return task; return task;
} }
function callTasks(initialTime) { function callTasks() {
isScheduling = false; isWaiting = false;
isProcessing = true; isProcessing = true;
let task = null; let task = null;
const previousPriorityLevel = currentPriorityLevel;
try { try {
let currentTime = initialTime;
task = first(); task = first();
// 循环执行task // 循环执行task
while (task !== null) { while (task !== null) {
if ( if (isOverTime()) {
task.expirationTime > currentTime && // 超过了deadline
isOverTime()
) {
// 任务的过期时间大于当前时间没达到此任务的过期时间且超过了deadline
break; break;
} }
const callback = task.callback; const callback = task.callback;
if (typeof callback === 'function') { if (callback !== null) {
task.callback = null; task.callback = null;
currentPriorityLevel = task.priorityLevel;
const didUserCallbackTimeout = task.expirationTime <= currentTime;
const continuationCallback = callback(didUserCallbackTimeout); callback();
currentTime = now();
// 执行callback返回函数重置callback if (task === first()) {
if (typeof continuationCallback === 'function') { shift();
task.callback = continuationCallback; } else { // 执行任务中可能插入了新任务
} else { remove(task);
if (task === first()) {
shift();
}
} }
} else { } else {
shift(); shift();
@ -110,8 +85,6 @@ function callTasks(initialTime) {
// 返回是否还有任务,如果有,说明是被中断了 // 返回是否还有任务,如果有,说明是被中断了
return task !== null; return task !== null;
} finally { } finally {
task = null;
currentPriorityLevel = previousPriorityLevel;
isProcessing = false; isProcessing = false;
} }
} }
@ -120,16 +93,9 @@ function cancelTask(task) {
task.callback = null; task.callback = null;
} }
function getCurrentPriorityLevel() {
return currentPriorityLevel;
}
export { export {
ImmediatePriority, ImmediatePriority,
NormalPriority, NormalPriority,
runSync,
runAsync, runAsync,
cancelTask, cancelTask,
getCurrentPriorityLevel,
now,
}; };

View File

@ -5,7 +5,7 @@
type Queue = Array<Node>; type Queue = Array<Node>;
type Node = { type Node = {
id: number; id: number;
expirationTime: number; order: number;
}; };
// 任务队列 // 任务队列
@ -15,9 +15,7 @@ export function add(node: Node): void {
// 查找第一个大于等于 value 的下标,都比 value 小则返回 -1 // 查找第一个大于等于 value 的下标,都比 value 小则返回 -1
const idx = getBiggerIdx(node); const idx = getBiggerIdx(node);
if (idx === 0) { if (idx === -1) {
taskQueue.unshift(node);
} else if (idx === -1) {
taskQueue.push(node); taskQueue.push(node);
} else { } else {
taskQueue.splice(idx, 0, node); taskQueue.splice(idx, 0, node);
@ -32,10 +30,11 @@ function getBiggerIdx(node: Node) {
while (left <= right) { while (left <= right) {
const middle = left + ((right - left) >> 1); const middle = left + ((right - left) >> 1);
if (compare(taskQueue[middle], node) > 0) if (compare(taskQueue[middle], node) > 0) {
right = middle - 1; right = middle - 1;
else } else {
left = middle + 1; left = middle + 1;
}
} }
return (left < taskQueue.length) ? left : -1; return (left < taskQueue.length) ? left : -1;
@ -51,8 +50,12 @@ export function shift(): Node | null {
return val !== undefined ? val : null; return val !== undefined ? val : null;
} }
export function remove(node: Node) {
taskQueue.splice(taskQueue.indexOf(node), 1);
}
function compare(a: Node, b: Node) { function compare(a: Node, b: Node) {
// 优先先用index排序其次用id // 优先先用index排序其次用id
const diff = a.expirationTime - b.expirationTime; const diff = a.order - b.order;
return diff !== 0 ? diff : a.id - b.id; return diff !== 0 ? diff : a.id - b.id;
} }