AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

PixiJS 源碼解讀:Runner 事件通知類

來源: 責編: 時間:2023-10-13 14:34:39 230觀看
導讀大家好,我是前端西瓜哥。PixiJS 的 Runner 類是高性能的事件通知類。其實就是一個簡易的發布訂閱庫。發布訂閱庫,我們比較熟悉的就是 Nodejs 的 EventEmitter。不過這個 Runner 的邏輯稍微有點特殊,后面會說它怎么特殊。

RgD28資訊網——每日最新資訊28at.com

大家好,我是前端西瓜哥。RgD28資訊網——每日最新資訊28at.com

PixiJS 的 Runner 類是高性能的事件通知類。其實就是一個簡易的發布訂閱庫。RgD28資訊網——每日最新資訊28at.com

發布訂閱庫,我們比較熟悉的就是 Nodejs 的 EventEmitter。RgD28資訊網——每日最新資訊28at.com

不過這個 Runner 的邏輯稍微有點特殊,后面會說它怎么特殊。RgD28資訊網——每日最新資訊28at.com

使用示例

import { Runner } from "@pixi/runner";const loadedRunner = new Runner("loaded");const listener = {  loaded(n1: number, n2: number) {    console.log("前端西瓜哥", n1, n2);  }};loadedRunner.add(listener);loadedRunner.emit(1, 2); // 輸出:前端西瓜哥 1 2

首先通過 new Runner(name) 創建一個 Runner 實例,這里需要傳入一個字符串類型的 name。RgD28資訊網——每日最新資訊28at.com

之后通過 runner.add 方法添加一個監聽器對象 listener。RgD28資訊網——每日最新資訊28at.com

最后通過 runner.emit 方法觸發事件,之前綁定的監聽器的 listener[name]  方法會被執行。RgD28資訊網——每日最新資訊28at.com

和我們熟悉的 Nodejs 的 EventEmitter 不一樣,有一些特別的點:RgD28資訊網——每日最新資訊28at.com

  • 一個 Runner 只能綁定一個事件,不像 EventEmitter 的 on 方法,還能多指定一個事件名。
  • 綁定的監聽器是一個對象,并會在觸發事件時調用 Runner 初始化時設置的 name 對應的函數。這樣做的優點是監聽器執行時 this 不會丟失。EventEmitter 綁定的直接就是一個函數。

然后它和 EventEmitter 一樣,是類型不安全的:emit 傳的參數并沒有限定。RgD28資訊網——每日最新資訊28at.com

源碼解讀

構造函數

首先是構造函數。RgD28資訊網——每日最新資訊28at.com

export class Runner {  public items: any[];  private _name: string;  private _aliasCount: number;  constructor(name: string) {    this.items = [];    this._name = name;    this._aliasCount = 0;  }  // ...}

簡單的初始化操作,這個 name 我們要保存下來,之后我們執行監聽器對象,需要這個 name 作為 key 去找到方法去執行。RgD28資訊網——每日最新資訊28at.com

items 是保存監聽器對象的數組。RgD28資訊網——每日最新資訊28at.com

_aliasCount 是一個標識,標識是否在 emit(觸發事件)階段,用于防止 emit 時改變了 items,導致不可預期的行為。RgD28資訊網——每日最新資訊28at.com

添加監聽器

然后是 add 方法,用于添加監聽器。RgD28資訊網——每日最新資訊28at.com

public add(item: unknown): this {  if ((item as any)[this._name]) {    this.ensureNonAliasedItems();    this.remove(item); // 如果存在,先刪除    this.items.push(item); // 添加的末尾  }  return this;}

監聽器對象必須有對應的 key 才能被添加進去。RgD28資訊網——每日最新資訊28at.com

為了保證 this.items 不出現多個相同的對象,會將其刪除。然后把監聽器對象放到 this.items 末尾。RgD28資訊網——每日最新資訊28at.com

返回 this,是為了實現鏈式調用。RgD28資訊網——每日最新資訊28at.com

this.ensureNonAliasedItems() 方法用于處理一些特殊 case。RgD28資訊網——每日最新資訊28at.com

比如在 emit 階段發生了 add 操作,PixiJS 會防止其在本輪 emit 被執行,為此會拷貝一份新的 items。RgD28資訊網——每日最新資訊28at.com

private ensureNonAliasedItems(): void {  if (this._aliasCount > 0 && this.items.length > 1) {    this._aliasCount = 0;    this.items = this.items.slice(0);  }}

事件觸發

emit 會觸發事件,別名有 dispatch、run。RgD28資訊網——每日最新資訊28at.com

public emit(  a0?: unknown,  a1?: unknown,  a2?: unknown,  a3?: unknown,  a4?: unknown,  a5?: unknown,  a6?: unknown,  a7?: unknown): this {  if (arguments.length > 8) {    throw new Error('max arguments reached');  }  const { name, items } = this;  this._aliasCount++;  for (let i = 0, len = items.length; i < len; i++) {    items[i][name](a0, a1, a2, a3, a4, a5, a6, a7);  }  if (items === this.items) {    this._aliasCount--;  }  return this;}

核心邏輯:遍歷 this.items 數組,順序執行監聽器的 key 為 this.name 的方法。RgD28資訊網——每日最新資訊28at.com

刪除監聽器

remove,刪除監聽器。RgD28資訊網——每日最新資訊28at.com

public remove(item: unknown): this {  const index = this.items.indexOf(item);  if (index !== -1) {    this.ensureNonAliasedItems();    this.items.splice(index, 1);  }  return this;}

其他方法

contains:查看指定對象是已經是被綁定為監聽器。RgD28資訊網——每日最新資訊28at.com

public contains(item: unknown): boolean {  return this.items.includes(item);}

removeAll:刪除所有監聽器.RgD28資訊網——每日最新資訊28at.com

public removeAll(): this {  this.ensureNonAliasedItems();  this.items.length = 0;  return this;}

destory:銷毀。銷毀后就不能再用了,否則會報錯。RgD28資訊網——每日最新資訊28at.com

public destroy(): void {  this.removeAll();  this.items = null;  this._name = null;}

empty,是一個 getter,判斷是否存在監聽器集合。PixiJS 確實喜歡用 getterRgD28資訊網——每日最新資訊28at.com

public get empty(): boolean {  return this.items.length === 0;}

結尾

通常我們會在 PixiJS 的類中看到名為 disposeRunner 的成員屬性,說明這個類會通過事件訂閱的方式和其他模塊通信。RgD28資訊網——每日最新資訊28at.com

發布訂閱庫我實在是分析得夠多了,基本的套路就 3 個:把監聽器函數放到有序表中,觸發事件時順序調用,支持刪除監聽器(3 種風格)。RgD28資訊網——每日最新資訊28at.com

PixiJS 的 Runner 功能并不多,其中特殊的調用邏輯(調用監聽器的特定 key)顯然是用于 PixiJS 內部模塊的風格。RgD28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-13254-0.htmlPixiJS 源碼解讀:Runner 事件通知類

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 如何更優雅的編程?面向接口編程四大法寶!

下一篇: 深入了解桶排序:原理、性能分析與 Java 實現

標簽:
  • 熱門焦點
Top