简体   繁体   English

我的反应事件池伪示例有意义吗?

[英]My react event pooling pseudo example makes sense?

TLDR TLDR

Can I check about implementation about event pooling logic in react.我可以检查有关反应中event pooling逻辑的实现吗?
And I want to know about event pooling principle:)我想知道event pooling原理:)

Question问题

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 in react package.任何知道event pooling实现在哪里的人都会react package。
Just comment to me please请给我评论

Pseudo event pooling伪事件池

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);
  };
}

Reference参考

  1. What is event pooling in react? 什么是反应中的事件池? - StackOverflow - 堆栈溢出
  2. Synthetic Event - React Document合成事件 - React 文档
  3. What's the meaning of Event Pooling?事件池的含义是什么?
  4. 진보된 쓰레드 풀링 기법 구현 - Korean 진보된 쓰레드 풀링 기법 구현 - 韩语

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM