[英]My react event pooling pseudo example makes sense?
Can I check about implementation about
event pooling
logic in react.我可以检查有关反应中
event pooling
逻辑的实现吗?
And I want to know aboutevent pooling
principle:)我想知道
event pooling
原理:)
When I deep dive to react document, I see about event pooling
.当我深入研究响应文档时,我看到了
event pooling
。
So, I'm so curious about what is event pooling
and I research about it.所以,我很好奇什么是
event pooling
,我研究了它。
And now I realize about thread pooling
.现在我意识到
thread pooling
。 So it is working similarly.所以它的工作方式类似。 So I make some pseudo
event pooling
logic.所以我做了一些伪
event pooling
逻辑。
And I want to know it does make sense?我想知道这有意义吗?
And any one who know about where
event pooling
implementation is inreact
package.任何知道
event pooling
实现在哪里的人都会react
package。
Just comment to me please请给我评论
EventPool pseudo implementation EventPool 伪实现
class EventPool {
private static instance: EventPool;
private taskQueue: Event[] = [];
private constructor() {
this.taskQueue = [];
}
public static shared() {
if (!EventPool.instance) {
EventPool.instance = new EventPool();
}
return EventPool.instance;
}
enqueue = (event: Event) => {
this.taskQueue = this.taskQueue.concat(event);
};
dequeue = (currentTarget: any) => {
this.taskQueue = this.taskQueue.filter(
(event: Event) => event.currentTarget === currentTarget
);
};
clear() {
// This function called before or after render
// (Commit -> Render -> EventPool.shared().clear()) or (Commit -> EventPool.shared().clear() -> Render)
this.taskQueue = this.taskQueue.filter((event) => event.isDone === true);
}
}
Event pseudo implementation about persist
关于
persist
的事件伪实现
class Event {
persist = () => {
// This is executed before EventPool.shared.clear
EventPool.shared().dequeue(this);
};
}
Here is quite simple example of SyntheticEvent
/ EventPool
pattern.这是
SyntheticEvent
/ EventPool
模式的非常简单的示例。 Obviously in real life it'll be a bit more complex to better respect of event's behavior, but this snippet have to shed some light on concept.显然,在现实生活中,更好地尊重事件的行为会有点复杂,但这个片段必须阐明一些概念。
class SyntheticEvent {
// all the following properties and methods are part of React's
// synthetic event, but we'll skip it here in favor of simplicity
// bubbles: boolean
// currentTarget: DOMEventTarget
// defaultPrevented: boolean
// eventPhase: number
// nativeEvent: DOMEvent
// preventDefault(): void {}
// isDefaultPrevented(): boolean { return true }
// stopPropagation(): void {}
// isPropagationStopped(): boolean { return true }
// target: DOMEventTarget
// timeStamp: number
// type: string
// for simplicity we'll consider here only 3 following properties
isTrusted: boolean
cancelable: boolean
persist: () => void
// this property helps to track status of each synthetic event
status: 'POOLED' | 'PERSISTED' | 'IN_USE'
constructor(status, onPersist: () => void) {
this.status = status;
this.persist = onPersist;
}
}
class EventPool {
private pool: SyntheticEvent[] = [];
constructor(initialPoolSize: number) {
// populating pool with pre-allocated events. We will try to re-use
// them as much as possible to reduce GC load
for(let i = 0; i < initialPoolSize; i++) {
this.allocateNewEvent();
}
}
pullEvent(nativeEvent): SyntheticEvent {
const syntheticEvent = this.getEventFromPool();
this.populateEvent(syntheticEvent, nativeEvent);
return syntheticEvent;
}
tryPushEvent(syntheticEvent: SyntheticEvent): void {
if(syntheticEvent.status !== 'PERSISTED') {
this.clearEvent(syntheticEvent);
}
}
private allocateNewEvent(): SyntheticEvent {
const newEvent = new SyntheticEvent( 'POOLED', () => {
newEvent.status = 'PERSISTED';
});
this.pool.push(newEvent);
return newEvent;
}
private getEventFromPool() {
let event = this.pool.find( e => e.status === 'POOLED' );
if(!event) {
event = this.allocateNewEvent();
}
return event;
}
/** Populates synthetic event with data from native event */
private populateEvent(syntheticEvent: SyntheticEvent, nativeEvent) {
syntheticEvent.status = 'IN_USE';
syntheticEvent.isTrusted = nativeEvent.isTrusted;
syntheticEvent.cancelable = nativeEvent.cancelable;
}
/** Sets all previously populated synthetic event fields to null for safe re-use */
private clearEvent(syntheticEvent: SyntheticEvent) {
syntheticEvent.status = 'POOLED';
syntheticEvent.isTrusted = null;
syntheticEvent.cancelable = null;
}
}
// Usage
const mainEventPool = new EventPool(2);
smth.onClick = nativeEvent => {
const syntheticEvent = mainEventPool.pullEvent(nativeEvent);
userDefinedOnClickHandler(syntheticEvent); // <-- on click handler defined by user
mainEventPool.tryPushEvent(syntheticEvent);
};
Event Pooling - React uses SyntheticEvent which is a wrapper for native browser events so that they have consistent properties across different browsers.
事件池——React 使用 SyntheticEvent,它是原生浏览器事件的包装器,因此它们在不同浏览器中具有一致的属性。 The event handlers that we have in any react-app are actually passed instances of SyntheticEvent unless we use nativeEvent attribute to get the underlying browser event.
我们在任何 react-app 中拥有的事件处理程序实际上是传递 SyntheticEvent 的实例,除非我们使用 nativeEvent 属性来获取底层浏览器事件。
Wrapping native event instances can cause performance issues since every synthetic event wrapper that's created will also need to be garbage collected at some point, which can be expensive in terms of CPU time.
包装本机事件实例可能会导致性能问题,因为创建的每个合成事件包装器也需要在某些时候进行垃圾收集,这在 CPU 时间方面可能会很昂贵。
React deals with this problem by allocating a synthetic instance pool.
React 通过分配一个合成实例池来处理这个问题。 Whenever an event is triggered, it takes an instance from the pool and populates its properties and reuses it.
每当触发事件时,它都会从池中获取一个实例并填充其属性并重用它。 When the event handler has finished running, all properties will be nullified and the synthetic event instance is released back into the pool.
当事件处理程序完成运行时,所有属性都将被取消,合成事件实例被释放回池中。 Hence, increasing the performance.
因此,提高性能。
https://stackoverflow.com/a/53500357/1040070 https://stackoverflow.com/a/53500357/1040070
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.