Match-id-7c9f92f0e54002e1e320dd2556d80d5da3b140f1

This commit is contained in:
* 2022-01-22 11:22:33 +08:00 committed by *
parent 571fabd459
commit 9c23f1be7e
7 changed files with 51 additions and 118 deletions

View File

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

View File

@ -160,39 +160,26 @@ function hideOrUnhideAllChildren(vNode, isHidden) {
function attachRef(vNode: VNode) {
const ref = vNode.ref;
if (ref !== null && ref !== undefined) {
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;
}
}
}
handleRef(vNode, ref, vNode.realNode);
}
function detachRef(vNode: VNode, isOldRef?: boolean) {
let ref = (isOldRef ? vNode.oldRef : vNode.ref);
handleRef(vNode, ref, null);
}
function handleRef(vNode: VNode, ref, val) {
if (ref !== null && ref !== undefined) {
let refType = typeof ref;
const refType = typeof ref;
if (refType === 'function') {
try {
ref(null);
} catch (error) {
handleSubmitError(vNode, error);
}
ref(val);
} else if (refType === 'object') {
(<RefType>ref).current = null;
(<RefType>ref).current = val;
} else {
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) {
treeRoot.shouldUpdate = treeRoot.childShouldUpdate;
const startVNode = getStartVNode();
// 置空task让才能加入新的render任务
treeRoot.task = null;
setProcessing(null);
const startVNode = getStartVNode();
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 browserCallback = null;
// 默认每次只运行5ms
const runTime = 5;
let deadline = 0;
export function isOverTime() {
return now() >= deadline;
return false;
}
// 1、设置deadline2、回调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);
}
}

View File

@ -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) {

View File

@ -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,
};

View File

@ -5,7 +5,7 @@
type Queue = Array<Node>;
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;
}