Match-id-846c52a6c0ddfcb4167efc73e2ef3aa481e59275
This commit is contained in:
commit
e63af180be
|
@ -37,35 +37,6 @@ export function shouldControlValue(): boolean {
|
|||
return changeEventTargets !== null && changeEventTargets.length > 0;
|
||||
}
|
||||
|
||||
// 从缓存队列中对受控组件进行赋值
|
||||
export function tryControlValue() {
|
||||
if (!changeEventTargets) {
|
||||
return;
|
||||
}
|
||||
changeEventTargets.forEach(target => {
|
||||
controlValue(target);
|
||||
});
|
||||
changeEventTargets = null;
|
||||
}
|
||||
|
||||
// 受控组件值重新赋值
|
||||
function controlValue(target: Element) {
|
||||
const props = getVNodeProps(target);
|
||||
if (props) {
|
||||
const type = getDomTag(target);
|
||||
switch (type) {
|
||||
case 'input':
|
||||
controlInputValue(<HTMLInputElement>target, props);
|
||||
break;
|
||||
case 'textarea':
|
||||
updateTextareaValue(<HTMLTextAreaElement>target, props);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function controlInputValue(inputDom: HTMLInputElement, props: Props) {
|
||||
const { name, type } = props;
|
||||
|
||||
|
@ -87,3 +58,32 @@ function controlInputValue(inputDom: HTMLInputElement, props: Props) {
|
|||
updateInputValue(inputDom, props);
|
||||
}
|
||||
}
|
||||
|
||||
// 受控组件值重新赋值
|
||||
function controlValue(target: Element) {
|
||||
const props = getVNodeProps(target);
|
||||
if (props) {
|
||||
const type = getDomTag(target);
|
||||
switch (type) {
|
||||
case 'input':
|
||||
controlInputValue(<HTMLInputElement>target, props);
|
||||
break;
|
||||
case 'textarea':
|
||||
updateTextareaValue(<HTMLTextAreaElement>target, props);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 从缓存队列中对受控组件进行赋值
|
||||
export function tryControlValue() {
|
||||
if (!changeEventTargets) {
|
||||
return;
|
||||
}
|
||||
changeEventTargets.forEach(target => {
|
||||
controlValue(target);
|
||||
});
|
||||
changeEventTargets = null;
|
||||
}
|
||||
|
|
|
@ -54,15 +54,12 @@ export type ReduxMiddleware = (
|
|||
type Reducer = (state: any, action: ReduxAction) => any;
|
||||
|
||||
function mergeData(state, data) {
|
||||
console.log('merging data', { state, data });
|
||||
if (!data) {
|
||||
console.log('!data');
|
||||
state.stateWrapper = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(data) && Array.isArray(state?.stateWrapper)) {
|
||||
console.log('data is array');
|
||||
state.stateWrapper.length = data.length;
|
||||
data.forEach((item, idx) => {
|
||||
if (item != state.stateWrapper[idx]) {
|
||||
|
@ -73,9 +70,10 @@ function mergeData(state, data) {
|
|||
}
|
||||
|
||||
if (typeof data === 'object' && typeof state?.stateWrapper === 'object') {
|
||||
console.log('data is object');
|
||||
Object.keys(state.stateWrapper).forEach(key => {
|
||||
if (!data.hasOwnProperty(key)) delete state.stateWrapper[key];
|
||||
if (!Object.prototype.hasOwnProperty.call(data, key)) {
|
||||
delete state.stateWrapper[key];
|
||||
}
|
||||
});
|
||||
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
|
@ -86,7 +84,6 @@ function mergeData(state, data) {
|
|||
return;
|
||||
}
|
||||
|
||||
console.log('data is primitive or type mismatch');
|
||||
state.stateWrapper = data;
|
||||
}
|
||||
|
||||
|
@ -106,7 +103,6 @@ export function createStore(reducer: Reducer, preloadedState?: any, enhancers?):
|
|||
if (result === undefined) {
|
||||
return;
|
||||
} // NOTE: reducer should never return undefined, in this case, do not change state
|
||||
// mergeData(state,result);
|
||||
state.stateWrapper = result;
|
||||
},
|
||||
},
|
||||
|
@ -115,10 +111,6 @@ export function createStore(reducer: Reducer, preloadedState?: any, enhancers?):
|
|||
},
|
||||
})();
|
||||
|
||||
// store.$subscribe(()=>{
|
||||
// console.log('changed');
|
||||
// });
|
||||
|
||||
const result = {
|
||||
reducer,
|
||||
getState: function () {
|
||||
|
@ -157,12 +149,6 @@ export function combineReducers(reducers: { [key: string]: Reducer }): Reducer {
|
|||
};
|
||||
}
|
||||
|
||||
export function applyMiddleware(...middlewares: ReduxMiddleware[]): (store: ReduxStoreHandler) => void {
|
||||
return store => {
|
||||
return applyMiddlewares(store, middlewares);
|
||||
};
|
||||
}
|
||||
|
||||
function applyMiddlewares(store: ReduxStoreHandler, middlewares: ReduxMiddleware[]): void {
|
||||
middlewares = middlewares.slice();
|
||||
middlewares.reverse();
|
||||
|
@ -173,6 +159,12 @@ function applyMiddlewares(store: ReduxStoreHandler, middlewares: ReduxMiddleware
|
|||
store.dispatch = dispatch;
|
||||
}
|
||||
|
||||
export function applyMiddleware(...middlewares: ReduxMiddleware[]): (store: ReduxStoreHandler) => void {
|
||||
return store => {
|
||||
return applyMiddlewares(store, middlewares);
|
||||
};
|
||||
}
|
||||
|
||||
type ActionCreator = (...params: any[]) => ReduxAction;
|
||||
type ActionCreators = { [key: string]: ActionCreator };
|
||||
export type BoundActionCreator = (...params: any[]) => void;
|
||||
|
|
|
@ -18,6 +18,12 @@ import type { VNode } from '../Types';
|
|||
import { getLastTimeHook, setLastTimeHook, setCurrentHook, getNextHook } from './BaseHook';
|
||||
import { HookStage, setHookStage } from './HookStage';
|
||||
|
||||
function resetGlobalVariable() {
|
||||
setHookStage(null);
|
||||
setLastTimeHook(null);
|
||||
setCurrentHook(null);
|
||||
}
|
||||
|
||||
// hook对外入口
|
||||
export function runFunctionWithHooks<Props extends Record<string, any>, Arg>(
|
||||
funcComp: (props: Props, arg: Arg) => any,
|
||||
|
@ -57,9 +63,3 @@ export function runFunctionWithHooks<Props extends Record<string, any>, Arg>(
|
|||
|
||||
return comp;
|
||||
}
|
||||
|
||||
function resetGlobalVariable() {
|
||||
setHookStage(null);
|
||||
setLastTimeHook(null);
|
||||
setCurrentHook(null);
|
||||
}
|
||||
|
|
|
@ -21,27 +21,17 @@ import { getHookStage, HookStage } from './HookStage';
|
|||
import { isArrayEqual } from '../utils/compare';
|
||||
import { getProcessingVNode } from '../GlobalVar';
|
||||
|
||||
export function useEffectImpl(effectFunc: () => (() => void) | void, deps?: Array<any> | null): void {
|
||||
// 异步触发的effect
|
||||
useEffect(effectFunc, deps, EffectConstant.Effect);
|
||||
}
|
||||
function createEffect(effectFunc, removeFunc, deps, effectConstant): Effect {
|
||||
const effect: Effect = {
|
||||
effect: effectFunc,
|
||||
removeEffect: removeFunc,
|
||||
dependencies: deps,
|
||||
effectConstant: effectConstant,
|
||||
};
|
||||
|
||||
export function useLayoutEffectImpl(effectFunc: () => (() => void) | void, deps?: Array<any> | null): void {
|
||||
// 同步触发的effect
|
||||
useEffect(effectFunc, deps, EffectConstant.LayoutEffect);
|
||||
}
|
||||
getProcessingVNode().effectList.push(effect);
|
||||
|
||||
function useEffect(effectFunc: () => (() => void) | void, deps: Array<any> | void | null, effectType: number): void {
|
||||
const stage = getHookStage();
|
||||
if (stage === null) {
|
||||
throwNotInFuncError();
|
||||
}
|
||||
|
||||
if (stage === HookStage.Init) {
|
||||
useEffectForInit(effectFunc, deps, effectType);
|
||||
} else if (stage === HookStage.Update) {
|
||||
useEffectForUpdate(effectFunc, deps, effectType);
|
||||
}
|
||||
return effect;
|
||||
}
|
||||
|
||||
export function useEffectForInit(effectFunc, deps, effectType): void {
|
||||
|
@ -76,15 +66,25 @@ export function useEffectForUpdate(effectFunc, deps, effectType): void {
|
|||
hook.state = createEffect(effectFunc, removeFunc, nextDeps, EffectConstant.DepsChange | effectType);
|
||||
}
|
||||
|
||||
function createEffect(effectFunc, removeFunc, deps, effectConstant): Effect {
|
||||
const effect: Effect = {
|
||||
effect: effectFunc,
|
||||
removeEffect: removeFunc,
|
||||
dependencies: deps,
|
||||
effectConstant: effectConstant,
|
||||
};
|
||||
function useEffect(effectFunc: () => (() => void) | void, deps: Array<any> | void | null, effectType: number): void {
|
||||
const stage = getHookStage();
|
||||
if (stage === null) {
|
||||
throwNotInFuncError();
|
||||
}
|
||||
|
||||
getProcessingVNode().effectList.push(effect);
|
||||
|
||||
return effect;
|
||||
if (stage === HookStage.Init) {
|
||||
useEffectForInit(effectFunc, deps, effectType);
|
||||
} else if (stage === HookStage.Update) {
|
||||
useEffectForUpdate(effectFunc, deps, effectType);
|
||||
}
|
||||
}
|
||||
|
||||
export function useEffectImpl(effectFunc: () => (() => void) | void, deps?: Array<any> | null): void {
|
||||
// 异步触发的effect
|
||||
useEffect(effectFunc, deps, EffectConstant.Effect);
|
||||
}
|
||||
|
||||
export function useLayoutEffectImpl(effectFunc: () => (() => void) | void, deps?: Array<any> | null): void {
|
||||
// 同步触发的effect
|
||||
useEffect(effectFunc, deps, EffectConstant.LayoutEffect);
|
||||
}
|
||||
|
|
|
@ -18,20 +18,6 @@ import { getHookStage } from './HookStage';
|
|||
import { throwNotInFuncError } from './BaseHook';
|
||||
import type { Ref } from './HookType';
|
||||
|
||||
export function useImperativeHandleImpl<R>(
|
||||
ref: { current: R | null } | ((any) => any) | null | void,
|
||||
func: () => R,
|
||||
dependencies?: Array<any> | null
|
||||
): void {
|
||||
const stage = getHookStage();
|
||||
if (stage === null) {
|
||||
throwNotInFuncError();
|
||||
}
|
||||
|
||||
const params = isNotNull(dependencies) ? dependencies.concat([ref]) : null;
|
||||
useLayoutEffectImpl(effectFunc.bind(null, func, ref), params);
|
||||
}
|
||||
|
||||
function isNotNull(object: any): boolean {
|
||||
return object !== null && object !== undefined;
|
||||
}
|
||||
|
@ -52,3 +38,17 @@ function effectFunc<R>(func: () => R, ref: Ref<R> | ((any) => any) | null): (()
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function useImperativeHandleImpl<R>(
|
||||
ref: { current: R | null } | ((any) => any) | null | void,
|
||||
func: () => R,
|
||||
dependencies?: Array<any> | null
|
||||
): void {
|
||||
const stage = getHookStage();
|
||||
if (stage === null) {
|
||||
throwNotInFuncError();
|
||||
}
|
||||
|
||||
const params = isNotNull(dependencies) ? dependencies.concat([ref]) : null;
|
||||
useLayoutEffectImpl(effectFunc.bind(null, func, ref), params);
|
||||
}
|
||||
|
|
|
@ -22,29 +22,6 @@ import { getHookStage, HookStage } from './HookStage';
|
|||
import type { VNode } from '../Types';
|
||||
import { getProcessingVNode } from '../GlobalVar';
|
||||
|
||||
export function useReducerImpl<S, P, A>(
|
||||
reducer: (S, A) => S,
|
||||
initArg: P,
|
||||
init?: (P) => S,
|
||||
isUseState?: boolean
|
||||
): [S, Trigger<A>] | void {
|
||||
const stage = getHookStage();
|
||||
if (stage === null) {
|
||||
throwNotInFuncError();
|
||||
}
|
||||
|
||||
if (stage === HookStage.Init) {
|
||||
return useReducerForInit(reducer, initArg, init, isUseState);
|
||||
} else if (stage === HookStage.Update) {
|
||||
// 获取当前的hook
|
||||
const currentHook = getCurrentHook();
|
||||
// 获取currentHook的更新数组
|
||||
const currentHookUpdates = (currentHook.state as Reducer<S, A>).updates;
|
||||
|
||||
return updateReducerHookState(currentHookUpdates, currentHook, reducer);
|
||||
}
|
||||
}
|
||||
|
||||
// 构造新的Update数组
|
||||
function insertUpdate<S, A>(action: A, hook: Hook<S, A>): Update<S, A> {
|
||||
const newUpdate: Update<S, A> = {
|
||||
|
@ -116,6 +93,25 @@ export function useReducerForInit<S, A>(reducer, initArg, init, isUseState?: boo
|
|||
return [hook.state.stateValue, trigger];
|
||||
}
|
||||
|
||||
// 计算stateValue值
|
||||
function calculateNewState<S, A>(currentHookUpdates: Array<Update<S, A>>, currentHook, reducer: (S, A) => S) {
|
||||
const reducerObj = currentHook.state;
|
||||
let state = reducerObj.stateValue;
|
||||
|
||||
// 循环遍历更新数组,计算新的状态值
|
||||
currentHookUpdates.forEach(update => {
|
||||
// 1. didCalculated = true 说明state已经计算过; 2. 如果来自 isUseState
|
||||
if (update.didCalculated && reducerObj.isUseState) {
|
||||
state = update.state;
|
||||
} else {
|
||||
const action = update.action;
|
||||
state = reducer(state, action);
|
||||
}
|
||||
});
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
// 更新hook.state
|
||||
function updateReducerHookState<S, A>(currentHookUpdates, currentHook, reducer): [S, Trigger<A>] {
|
||||
if (currentHookUpdates !== null) {
|
||||
|
@ -135,21 +131,25 @@ function updateReducerHookState<S, A>(currentHookUpdates, currentHook, reducer):
|
|||
return [currentHook.state.stateValue, currentHook.state.trigger];
|
||||
}
|
||||
|
||||
// 计算stateValue值
|
||||
function calculateNewState<S, A>(currentHookUpdates: Array<Update<S, A>>, currentHook, reducer: (S, A) => S) {
|
||||
const reducerObj = currentHook.state;
|
||||
let state = reducerObj.stateValue;
|
||||
export function useReducerImpl<S, P, A>(
|
||||
reducer: (S, A) => S,
|
||||
initArg: P,
|
||||
init?: (P) => S,
|
||||
isUseState?: boolean
|
||||
): [S, Trigger<A>] | void {
|
||||
const stage = getHookStage();
|
||||
if (stage === null) {
|
||||
throwNotInFuncError();
|
||||
}
|
||||
|
||||
// 循环遍历更新数组,计算新的状态值
|
||||
currentHookUpdates.forEach(update => {
|
||||
// 1. didCalculated = true 说明state已经计算过; 2. 如果来自 isUseState
|
||||
if (update.didCalculated && reducerObj.isUseState) {
|
||||
state = update.state;
|
||||
} else {
|
||||
const action = update.action;
|
||||
state = reducer(state, action);
|
||||
}
|
||||
});
|
||||
if (stage === HookStage.Init) {
|
||||
return useReducerForInit(reducer, initArg, init, isUseState);
|
||||
} else if (stage === HookStage.Update) {
|
||||
// 获取当前的hook
|
||||
const currentHook = getCurrentHook();
|
||||
// 获取currentHook的更新数组
|
||||
const currentHookUpdates = (currentHook.state as Reducer<S, A>).updates;
|
||||
|
||||
return state;
|
||||
return updateReducerHookState(currentHookUpdates, currentHook, reducer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,28 +40,6 @@ export function isSchedulingEffects() {
|
|||
return isScheduling;
|
||||
}
|
||||
|
||||
export function callUseEffects(vNode: VNode) {
|
||||
const effectList: EffectList = vNode.effectList;
|
||||
if (effectList !== null) {
|
||||
effectList.forEach(effect => {
|
||||
const { effectConstant } = effect;
|
||||
if (
|
||||
(effectConstant & EffectConstant.Effect) !== EffectConstant.NoEffect &&
|
||||
(effectConstant & EffectConstant.DepsChange) !== EffectConstant.NoEffect
|
||||
) {
|
||||
hookEffects.push(effect);
|
||||
hookRemoveEffects.push(effect);
|
||||
|
||||
// 异步调用
|
||||
if (!isScheduling) {
|
||||
isScheduling = true;
|
||||
runAsync(runAsyncEffects);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function runAsyncEffects() {
|
||||
const preMode = copyExecuteMode();
|
||||
changeMode(InRender, true);
|
||||
|
@ -98,6 +76,28 @@ export function runAsyncEffects() {
|
|||
setExecuteMode(preMode);
|
||||
}
|
||||
|
||||
export function callUseEffects(vNode: VNode) {
|
||||
const effectList: EffectList = vNode.effectList;
|
||||
if (effectList !== null) {
|
||||
effectList.forEach(effect => {
|
||||
const { effectConstant } = effect;
|
||||
if (
|
||||
(effectConstant & EffectConstant.Effect) !== EffectConstant.NoEffect &&
|
||||
(effectConstant & EffectConstant.DepsChange) !== EffectConstant.NoEffect
|
||||
) {
|
||||
hookEffects.push(effect);
|
||||
hookRemoveEffects.push(effect);
|
||||
|
||||
// 异步调用
|
||||
if (!isScheduling) {
|
||||
isScheduling = true;
|
||||
runAsync(runAsyncEffects);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 在销毁vNode的时候调用remove
|
||||
export function callEffectRemove(vNode: VNode) {
|
||||
const effectList: EffectList = vNode.effectList;
|
||||
|
|
|
@ -154,18 +154,6 @@ function hideOrUnhideAllChildren(vNode, isHidden) {
|
|||
);
|
||||
}
|
||||
|
||||
function attachRef(vNode: VNode) {
|
||||
const ref = vNode.ref;
|
||||
|
||||
handleRef(vNode, ref, vNode.realNode);
|
||||
}
|
||||
|
||||
function detachRef(vNode: VNode, isOldRef?: boolean) {
|
||||
const ref = isOldRef ? vNode.oldRef : vNode.ref;
|
||||
|
||||
handleRef(vNode, ref, null);
|
||||
}
|
||||
|
||||
function handleRef(vNode: VNode, ref, val) {
|
||||
if (ref !== null && ref !== undefined) {
|
||||
const refType = typeof ref;
|
||||
|
@ -182,6 +170,18 @@ function handleRef(vNode: VNode, ref, val) {
|
|||
}
|
||||
}
|
||||
|
||||
function attachRef(vNode: VNode) {
|
||||
const ref = vNode.ref;
|
||||
|
||||
handleRef(vNode, ref, vNode.realNode);
|
||||
}
|
||||
|
||||
function detachRef(vNode: VNode, isOldRef?: boolean) {
|
||||
const ref = isOldRef ? vNode.oldRef : vNode.ref;
|
||||
|
||||
handleRef(vNode, ref, null);
|
||||
}
|
||||
|
||||
// 卸载一个vNode,不会递归
|
||||
function unmountVNode(vNode: VNode): void {
|
||||
switch (vNode.tag) {
|
||||
|
@ -217,6 +217,9 @@ function unmountVNode(vNode: VNode): void {
|
|||
unmountDomComponents(vNode);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -413,6 +416,9 @@ function submitUpdate(vNode: VNode): void {
|
|||
listenToPromise(vNode);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,63 +41,6 @@ const LOOPING_UPDATE_LIMIT = 50;
|
|||
let loopingUpdateCount = 0;
|
||||
let lastRoot: VNode | null = null;
|
||||
|
||||
export function submitToRender(treeRoot) {
|
||||
treeRoot.shouldUpdate = treeRoot.childShouldUpdate;
|
||||
// 置空task,让才能加入新的render任务
|
||||
treeRoot.task = null;
|
||||
|
||||
const startVNode = getStartVNode();
|
||||
|
||||
if (FlagUtils.hasAnyFlag(startVNode)) {
|
||||
// 把自己加上
|
||||
if (startVNode.dirtyNodes === null) {
|
||||
startVNode.dirtyNodes = [startVNode];
|
||||
} else {
|
||||
startVNode.dirtyNodes.push(startVNode);
|
||||
}
|
||||
}
|
||||
|
||||
const dirtyNodes = startVNode.dirtyNodes;
|
||||
if (dirtyNodes !== null && dirtyNodes.length) {
|
||||
const preMode = copyExecuteMode();
|
||||
changeMode(InRender, true);
|
||||
|
||||
prepareForSubmit();
|
||||
// before submit阶段
|
||||
beforeSubmit(dirtyNodes);
|
||||
|
||||
// submit阶段
|
||||
submit(dirtyNodes);
|
||||
|
||||
resetAfterSubmit();
|
||||
|
||||
// after submit阶段
|
||||
afterSubmit(dirtyNodes);
|
||||
|
||||
setExecuteMode(preMode);
|
||||
dirtyNodes.length = 0;
|
||||
startVNode.dirtyNodes = null;
|
||||
}
|
||||
|
||||
if (isSchedulingEffects()) {
|
||||
setSchedulingEffects(false);
|
||||
}
|
||||
|
||||
// 统计root同步重渲染的次数,如果太多可能是无线循环
|
||||
countLoopingUpdate(treeRoot);
|
||||
|
||||
// 在退出`submit` 之前始终调用此函数,以确保任何已计划在此根上执行的update被执行。
|
||||
tryRenderFromRoot(treeRoot);
|
||||
|
||||
if (rootThrowError) {
|
||||
const error = rootThrowError;
|
||||
rootThrowError = null;
|
||||
throw error;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function beforeSubmit(dirtyNodes: Array<VNode>) {
|
||||
let node;
|
||||
const nodesLength = dirtyNodes.length;
|
||||
|
@ -214,3 +157,60 @@ export function checkLoopingUpdateLimit() {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function submitToRender(treeRoot) {
|
||||
treeRoot.shouldUpdate = treeRoot.childShouldUpdate;
|
||||
// 置空task,让才能加入新的render任务
|
||||
treeRoot.task = null;
|
||||
|
||||
const startVNode = getStartVNode();
|
||||
|
||||
if (FlagUtils.hasAnyFlag(startVNode)) {
|
||||
// 把自己加上
|
||||
if (startVNode.dirtyNodes === null) {
|
||||
startVNode.dirtyNodes = [startVNode];
|
||||
} else {
|
||||
startVNode.dirtyNodes.push(startVNode);
|
||||
}
|
||||
}
|
||||
|
||||
const dirtyNodes = startVNode.dirtyNodes;
|
||||
if (dirtyNodes !== null && dirtyNodes.length) {
|
||||
const preMode = copyExecuteMode();
|
||||
changeMode(InRender, true);
|
||||
|
||||
prepareForSubmit();
|
||||
// before submit阶段
|
||||
beforeSubmit(dirtyNodes);
|
||||
|
||||
// submit阶段
|
||||
submit(dirtyNodes);
|
||||
|
||||
resetAfterSubmit();
|
||||
|
||||
// after submit阶段
|
||||
afterSubmit(dirtyNodes);
|
||||
|
||||
setExecuteMode(preMode);
|
||||
dirtyNodes.length = 0;
|
||||
startVNode.dirtyNodes = null;
|
||||
}
|
||||
|
||||
if (isSchedulingEffects()) {
|
||||
setSchedulingEffects(false);
|
||||
}
|
||||
|
||||
// 统计root同步重渲染的次数,如果太多可能是无线循环
|
||||
countLoopingUpdate(treeRoot);
|
||||
|
||||
// 在退出`submit` 之前始终调用此函数,以确保任何已计划在此根上执行的update被执行。
|
||||
tryRenderFromRoot(treeRoot);
|
||||
|
||||
if (rootThrowError) {
|
||||
const error = rootThrowError;
|
||||
rootThrowError = null;
|
||||
throw error;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,14 @@ export function isOverTime() {
|
|||
return false;
|
||||
}
|
||||
|
||||
function asyncCall() {
|
||||
if (isTestRuntime) {
|
||||
setTimeout(callRenderTasks, 0);
|
||||
} else {
|
||||
port2.postMessage(null);
|
||||
}
|
||||
}
|
||||
|
||||
// 1、设置deadline;2、回调TaskExecutor传过来的browserCallback
|
||||
const callRenderTasks = () => {
|
||||
if (browserCallback === null) {
|
||||
|
@ -61,14 +69,6 @@ if (typeof MessageChannel === 'function') {
|
|||
isTestRuntime = true;
|
||||
}
|
||||
|
||||
function asyncCall() {
|
||||
if (isTestRuntime) {
|
||||
setTimeout(callRenderTasks, 0);
|
||||
} else {
|
||||
port2.postMessage(null);
|
||||
}
|
||||
}
|
||||
|
||||
export function requestBrowserCallback(callback) {
|
||||
browserCallback = callback;
|
||||
|
||||
|
|
|
@ -27,16 +27,6 @@ let callingQueueTask: any | null = null;
|
|||
// 防止重入
|
||||
let isCallingRenderQueue = false;
|
||||
|
||||
export function callRenderQueueImmediate() {
|
||||
if (callingQueueTask !== null) {
|
||||
// 取消异步调度
|
||||
cancelTask(callingQueueTask);
|
||||
callingQueueTask = null;
|
||||
}
|
||||
|
||||
callRenderQueue();
|
||||
}
|
||||
|
||||
// 执行render回调
|
||||
function callRenderQueue() {
|
||||
if (!isCallingRenderQueue && renderQueue !== null) {
|
||||
|
@ -58,6 +48,16 @@ function callRenderQueue() {
|
|||
}
|
||||
}
|
||||
|
||||
export function callRenderQueueImmediate() {
|
||||
if (callingQueueTask !== null) {
|
||||
// 取消异步调度
|
||||
cancelTask(callingQueueTask);
|
||||
callingQueueTask = null;
|
||||
}
|
||||
|
||||
callRenderQueue();
|
||||
}
|
||||
|
||||
export function pushRenderCallback(callback: RenderCallback) {
|
||||
if (renderQueue === null) {
|
||||
renderQueue = [callback];
|
||||
|
|
|
@ -200,6 +200,8 @@ export class VNode {
|
|||
break;
|
||||
case Profiler:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,6 +194,8 @@ export function createVNode(tag: VNodeTag | string, ...secondArg) {
|
|||
|
||||
vNode.updates = [];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return vNode;
|
||||
|
|
|
@ -169,13 +169,6 @@ export function findDOMByClassInst(inst) {
|
|||
return domVNode !== null ? domVNode.realNode : null;
|
||||
}
|
||||
|
||||
// 判断dom树是否已经挂载
|
||||
export function isMounted(vNode: VNode) {
|
||||
const rootNode = getTreeRootVNode(vNode);
|
||||
// 如果根节点是 Dom 类型节点,表示已经挂载
|
||||
return rootNode.tag === TreeRoot;
|
||||
}
|
||||
|
||||
function getTreeRootVNode(vNode) {
|
||||
let node = vNode;
|
||||
while (node.parent) {
|
||||
|
@ -184,6 +177,13 @@ function getTreeRootVNode(vNode) {
|
|||
return node;
|
||||
}
|
||||
|
||||
// 判断dom树是否已经挂载
|
||||
export function isMounted(vNode: VNode) {
|
||||
const rootNode = getTreeRootVNode(vNode);
|
||||
// 如果根节点是 Dom 类型节点,表示已经挂载
|
||||
return rootNode.tag === TreeRoot;
|
||||
}
|
||||
|
||||
// 找到相邻的DOM
|
||||
export function getSiblingDom(vNode: VNode): Element | null {
|
||||
let node: VNode = vNode;
|
||||
|
|
Loading…
Reference in New Issue