From 77a69dd0fc4c1bced54c2daa0027049c7231f86d Mon Sep 17 00:00:00 2001 From: pianruijie <13522335863@163.com> Date: Wed, 30 Nov 2022 11:19:57 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=8A=A8=E4=BD=9C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=98=B2=E6=8A=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../amis-core/src/utils/renderer-event.ts | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/packages/amis-core/src/utils/renderer-event.ts b/packages/amis-core/src/utils/renderer-event.ts index 9d6ff0605..492711e10 100644 --- a/packages/amis-core/src/utils/renderer-event.ts +++ b/packages/amis-core/src/utils/renderer-event.ts @@ -2,10 +2,15 @@ import {ListenerAction, ListenerContext, runActions} from '../actions/Action'; import {RendererProps} from '../factory'; import {IScopedContext} from '../Scoped'; import {createObject} from './object'; +import debounce from 'lodash/debounce'; // 事件监听器 export interface EventListeners { [propName: string]: { + debounceConfig: { + open: boolean, + interval?: number + }, weight?: number; // 权重 actions: ListenerAction[]; // 执行的动作集 }; @@ -26,7 +31,12 @@ export interface RendererEventListener { renderer: React.Component; type: string; weight: number; + debounceConfig: { + open: boolean, + interval?: number + }, actions: ListenerAction[]; + executing?: boolean; } // 将事件上下文转成事件对象 @@ -82,6 +92,7 @@ export const bindEvent = (renderer: any) => { if (!renderer) { return undefined; } + console.log(rendererEventListeners); const listeners: EventListeners = renderer.props.$schema.onEvent; if (listeners) { // 暂存 @@ -94,6 +105,7 @@ export const bindEvent = (renderer: any) => { rendererEventListeners.push({ renderer, type: key, + debounceConfig: listeners[key].debounceConfig || {open: false}, weight: listeners[key].weight || 0, actions: listeners[key].actions }); @@ -118,7 +130,7 @@ export async function dispatchEvent( data: any, broadcast?: RendererEvent ): Promise | void> { - let unbindEvent = null; + let unbindEvent: (() => void) | null | undefined = null; const eventName = typeof e === 'string' ? e : e.type; renderer?.props?.env?.beforeDispatchEvent?.( @@ -156,25 +168,47 @@ export async function dispatchEvent( const listeners = rendererEventListeners .filter( (item: RendererEventListener) => - item.type === eventName && + item.type === eventName && !item.executing && (broadcast ? true : item.renderer === renderer) ) .sort( (prev: RendererEventListener, next: RendererEventListener) => next.weight - prev.weight ); - + let executedCount = 0; + const checkExecuted = () => { + executedCount++; + if (executedCount === listeners.length) { + unbindEvent?.(); + } + } for (let listener of listeners) { - await runActions(listener.actions, listener.renderer, rendererEvent); - + if (listener.debounceConfig.open) { + rendererEventListeners.forEach(item => { + // 找到事件队列中正在执行的事件加上标识,下次待执行队列就会把这个事件过滤掉 + if (item.renderer === listener.renderer && listener.type === item.type) { + item.executing = true; + } + }); + debounce(async () => { + await runActions(listener.actions, listener.renderer, rendererEvent); + checkExecuted(); + }, + listener.debounceConfig.interval, + { + trailing: true, + leading: false + })(); + } else { + await runActions(listener.actions, listener.renderer, rendererEvent); + checkExecuted(); + } // 停止后续监听器执行 if (rendererEvent.stoped) { break; } } - unbindEvent?.(); - return Promise.resolve(rendererEvent); } From bd206bb4f8bb1164945433888df2549e54850d5d Mon Sep 17 00:00:00 2001 From: pianruijie <13522335863@163.com> Date: Wed, 30 Nov 2022 11:20:30 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E5=8E=BB=E6=8E=89log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-core/src/utils/renderer-event.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/amis-core/src/utils/renderer-event.ts b/packages/amis-core/src/utils/renderer-event.ts index 492711e10..b2277595a 100644 --- a/packages/amis-core/src/utils/renderer-event.ts +++ b/packages/amis-core/src/utils/renderer-event.ts @@ -92,7 +92,6 @@ export const bindEvent = (renderer: any) => { if (!renderer) { return undefined; } - console.log(rendererEventListeners); const listeners: EventListeners = renderer.props.$schema.onEvent; if (listeners) { // 暂存 From 45c601da81d4b593f49f1bfb906014e58cdbdc5d Mon Sep 17 00:00:00 2001 From: pianruijie <13522335863@163.com> Date: Wed, 30 Nov 2022 21:23:20 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E9=98=B2=E6=8A=96=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../amis-core/src/utils/renderer-event.ts | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/packages/amis-core/src/utils/renderer-event.ts b/packages/amis-core/src/utils/renderer-event.ts index b2277595a..d8a662129 100644 --- a/packages/amis-core/src/utils/renderer-event.ts +++ b/packages/amis-core/src/utils/renderer-event.ts @@ -37,8 +37,8 @@ export interface RendererEventListener { }, actions: ListenerAction[]; executing?: boolean; + debounceInstance?: any; } - // 将事件上下文转成事件对象 export type RendererEvent = { context: T; @@ -96,10 +96,23 @@ export const bindEvent = (renderer: any) => { if (listeners) { // 暂存 for (let key of Object.keys(listeners)) { - const listener = rendererEventListeners.some( + const listener = rendererEventListeners.find( (item: RendererEventListener) => item.renderer === renderer && item.type === key ); + if (listener?.executing) { + listener?.debounceInstance?.cancel?.(); + rendererEventListeners = rendererEventListeners.filter( + (item: RendererEventListener) => + !(item.renderer === listener.renderer && item.type === listener.type)); + rendererEventListeners.push({ + renderer, + type: key, + debounceConfig: listener.debounceConfig || {open: false}, + weight: listener.weight || 0, + actions: listener.actions + }); + } if (!listener) { rendererEventListeners.push({ renderer, @@ -167,7 +180,7 @@ export async function dispatchEvent( const listeners = rendererEventListeners .filter( (item: RendererEventListener) => - item.type === eventName && !item.executing && + item.type === eventName && (broadcast ? true : item.renderer === renderer) ) .sort( @@ -183,21 +196,25 @@ export async function dispatchEvent( } for (let listener of listeners) { if (listener.debounceConfig.open) { + const debounced = debounce( + async () => { + await runActions(listener.actions, listener.renderer, rendererEvent); + checkExecuted(); + }, + listener.debounceConfig.interval, + { + trailing: true, + leading: false + } + ); rendererEventListeners.forEach(item => { // 找到事件队列中正在执行的事件加上标识,下次待执行队列就会把这个事件过滤掉 if (item.renderer === listener.renderer && listener.type === item.type) { item.executing = true; + item.debounceInstance = debounced; } }); - debounce(async () => { - await runActions(listener.actions, listener.renderer, rendererEvent); - checkExecuted(); - }, - listener.debounceConfig.interval, - { - trailing: true, - leading: false - })(); + debounced(); } else { await runActions(listener.actions, listener.renderer, rendererEvent); checkExecuted(); From 3bdf1fd7e93d26b21f4cba1382ef2d8dd7fef5dc Mon Sep 17 00:00:00 2001 From: pianruijie <13522335863@163.com> Date: Thu, 1 Dec 2022 16:42:49 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../amis-core/src/utils/renderer-event.ts | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/amis-core/src/utils/renderer-event.ts b/packages/amis-core/src/utils/renderer-event.ts index d8a662129..ca5a23ddb 100644 --- a/packages/amis-core/src/utils/renderer-event.ts +++ b/packages/amis-core/src/utils/renderer-event.ts @@ -4,13 +4,17 @@ import {IScopedContext} from '../Scoped'; import {createObject} from './object'; import debounce from 'lodash/debounce'; + +interface debounceConfig { + open: boolean; + wait?: number; + leading?: boolean; + trailing?: boolean; +} // 事件监听器 export interface EventListeners { [propName: string]: { - debounceConfig: { - open: boolean, - interval?: number - }, + debounceConfig?: debounceConfig, weight?: number; // 权重 actions: ListenerAction[]; // 执行的动作集 }; @@ -21,7 +25,8 @@ export interface OnEventProps { onEvent?: { [propName: string]: { weight?: number; // 权重 - actions: ListenerAction[]; // 执行的动作集 + actions: ListenerAction[]; // 执行的动作集, + debounceConfig?: debounceConfig, }; }; } @@ -31,10 +36,7 @@ export interface RendererEventListener { renderer: React.Component; type: string; weight: number; - debounceConfig: { - open: boolean, - interval?: number - }, + debounceConfig: debounceConfig, actions: ListenerAction[]; executing?: boolean; debounceInstance?: any; @@ -195,16 +197,17 @@ export async function dispatchEvent( } } for (let listener of listeners) { - if (listener.debounceConfig.open) { + const {open, wait=100, trailing=true, leading=false} = listener?.debounceConfig; + if (open) { const debounced = debounce( async () => { await runActions(listener.actions, listener.renderer, rendererEvent); checkExecuted(); }, - listener.debounceConfig.interval, + wait, { - trailing: true, - leading: false + trailing, + leading } ); rendererEventListeners.forEach(item => { From b1fcbd8bddcdc611fda37c2dec15ce95441ab394 Mon Sep 17 00:00:00 2001 From: pianruijie <13522335863@163.com> Date: Thu, 1 Dec 2022 20:06:59 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=98=B2=E6=8A=96?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../amis-core/src/utils/renderer-event.ts | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/amis-core/src/utils/renderer-event.ts b/packages/amis-core/src/utils/renderer-event.ts index ca5a23ddb..965fcb802 100644 --- a/packages/amis-core/src/utils/renderer-event.ts +++ b/packages/amis-core/src/utils/renderer-event.ts @@ -6,7 +6,7 @@ import debounce from 'lodash/debounce'; interface debounceConfig { - open: boolean; + maxWait?: number; wait?: number; leading?: boolean; trailing?: boolean; @@ -14,7 +14,7 @@ interface debounceConfig { // 事件监听器 export interface EventListeners { [propName: string]: { - debounceConfig?: debounceConfig, + debounce?: debounceConfig, weight?: number; // 权重 actions: ListenerAction[]; // 执行的动作集 }; @@ -26,7 +26,7 @@ export interface OnEventProps { [propName: string]: { weight?: number; // 权重 actions: ListenerAction[]; // 执行的动作集, - debounceConfig?: debounceConfig, + debounce?: debounceConfig, }; }; } @@ -36,7 +36,7 @@ export interface RendererEventListener { renderer: React.Component; type: string; weight: number; - debounceConfig: debounceConfig, + debounce: debounceConfig | null, actions: ListenerAction[]; executing?: boolean; debounceInstance?: any; @@ -110,7 +110,7 @@ export const bindEvent = (renderer: any) => { rendererEventListeners.push({ renderer, type: key, - debounceConfig: listener.debounceConfig || {open: false}, + debounce: listener.debounce || null, weight: listener.weight || 0, actions: listener.actions }); @@ -119,7 +119,7 @@ export const bindEvent = (renderer: any) => { rendererEventListeners.push({ renderer, type: key, - debounceConfig: listeners[key].debounceConfig || {open: false}, + debounce: listeners[key].debounce || null, weight: listeners[key].weight || 0, actions: listeners[key].actions }); @@ -196,9 +196,10 @@ export async function dispatchEvent( unbindEvent?.(); } } + console.log(listeners); for (let listener of listeners) { - const {open, wait=100, trailing=true, leading=false} = listener?.debounceConfig; - if (open) { + const {wait=100, trailing=true, leading=false, maxWait=10000} = listener?.debounce || {}; + if (listener?.debounce) { const debounced = debounce( async () => { await runActions(listener.actions, listener.renderer, rendererEvent); @@ -207,7 +208,8 @@ export async function dispatchEvent( wait, { trailing, - leading + leading, + maxWait } ); rendererEventListeners.forEach(item => { From 61e57b7733edb46ea8cdfb42bfa0013fe21d07c2 Mon Sep 17 00:00:00 2001 From: pianruijie <13522335863@163.com> Date: Thu, 1 Dec 2022 20:10:35 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=98=B2=E6=8A=96?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-core/src/utils/renderer-event.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/amis-core/src/utils/renderer-event.ts b/packages/amis-core/src/utils/renderer-event.ts index 965fcb802..133ac7c5e 100644 --- a/packages/amis-core/src/utils/renderer-event.ts +++ b/packages/amis-core/src/utils/renderer-event.ts @@ -196,7 +196,6 @@ export async function dispatchEvent( unbindEvent?.(); } } - console.log(listeners); for (let listener of listeners) { const {wait=100, trailing=true, leading=false, maxWait=10000} = listener?.debounce || {}; if (listener?.debounce) { From f6d15e536fd7971f056bfa85d5e7f723b3782466 Mon Sep 17 00:00:00 2001 From: pianruijie <13522335863@163.com> Date: Fri, 2 Dec 2022 10:26:36 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E9=87=8D=E6=96=B0=E8=B7=91=E5=8D=95?= =?UTF-8?q?=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-core/src/utils/renderer-event.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/amis-core/src/utils/renderer-event.ts b/packages/amis-core/src/utils/renderer-event.ts index 133ac7c5e..6729799dc 100644 --- a/packages/amis-core/src/utils/renderer-event.ts +++ b/packages/amis-core/src/utils/renderer-event.ts @@ -228,7 +228,6 @@ export async function dispatchEvent( break; } } - return Promise.resolve(rendererEvent); } From c724946db8c4b441a191287dd1f715ae519770a3 Mon Sep 17 00:00:00 2001 From: pianruijie <13522335863@163.com> Date: Fri, 2 Dec 2022 15:38:16 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A3=B0=E6=98=8E?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-core/src/types.ts | 3 +++ packages/amis-core/src/utils/renderer-event.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/amis-core/src/types.ts b/packages/amis-core/src/types.ts index dced8447d..cfc521ebe 100644 --- a/packages/amis-core/src/types.ts +++ b/packages/amis-core/src/types.ts @@ -1,6 +1,8 @@ // https://json-schema.org/draft-07/json-schema-release-notes.html import type {JSONSchema7} from 'json-schema'; import {ListenerAction} from './actions/Action'; +import {debounceConfig} from './utils/renderer-event'; + export interface Option { /** @@ -592,6 +594,7 @@ export interface BaseSchemaWithoutType { [propName: string]: { weight?: number; // 权重 actions: ListenerAction[]; // 执行的动作集 + debounce?: debounceConfig, }; }; /** diff --git a/packages/amis-core/src/utils/renderer-event.ts b/packages/amis-core/src/utils/renderer-event.ts index 6729799dc..b61ca23af 100644 --- a/packages/amis-core/src/utils/renderer-event.ts +++ b/packages/amis-core/src/utils/renderer-event.ts @@ -5,7 +5,7 @@ import {createObject} from './object'; import debounce from 'lodash/debounce'; -interface debounceConfig { +export interface debounceConfig { maxWait?: number; wait?: number; leading?: boolean; From 8231ae3f66091853a457259368ac99a5baa0688d Mon Sep 17 00:00:00 2001 From: pianruijie <13522335863@163.com> Date: Mon, 5 Dec 2022 16:58:00 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E9=87=8D=E8=B7=91=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-core/src/utils/renderer-event.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/amis-core/src/utils/renderer-event.ts b/packages/amis-core/src/utils/renderer-event.ts index b61ca23af..43b53a8a8 100644 --- a/packages/amis-core/src/utils/renderer-event.ts +++ b/packages/amis-core/src/utils/renderer-event.ts @@ -223,6 +223,7 @@ export async function dispatchEvent( await runActions(listener.actions, listener.renderer, rendererEvent); checkExecuted(); } + // 停止后续监听器执行 if (rendererEvent.stoped) { break;