国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

玩玩JS設(shè)計模式之:發(fā)布/訂閱

zhaochunqi / 2945人閱讀

摘要:前言的模塊功能強大,除了常規(guī)的監(jiān)聽觸發(fā),還支持事件順序,本文只是寫著玩玩,真正要用的話,還是選擇成熟穩(wěn)定的東西較好內(nèi)容概覽以下訂閱監(jiān)聽發(fā)布觸發(fā)一般來說,先訂閱事件,再發(fā)布事件就像打電話一樣,電話沒撥通訂閱,你就開始說話要干嘛干嘛發(fā)布,這時候

前言

Node.js的 events 模塊功能強大,除了常規(guī)的監(jiān)聽、觸發(fā),還支持事件順序(prependListener),本文只是寫著玩玩,真正要用的話,還是選擇成熟穩(wěn)定的東西較好!

內(nèi)容概覽: 以下訂閱=監(jiān)聽、發(fā)布=觸發(fā);一般來說,先訂閱事件再發(fā)布事件;就像打電話一樣,電話沒撥通(訂閱),你就開始說話要干嘛干嘛(發(fā)布),這時候訂閱是無效的!!!因為觸發(fā)在前、監(jiān)聽在后,觸發(fā)的時候沒有監(jiān)聽,監(jiān)聽的時候已經(jīng)結(jié)束,二者不在一個頻道!!! 溝通就是無效的。。。

四個功能:

訂閱on

訂閱once(一次性

發(fā)布emit

注銷off

錯誤監(jiān)聽error

構(gòu)造函數(shù)
// 發(fā)布訂閱,回調(diào)函數(shù)版本
function EvtEmit() {
  // 事件參數(shù)隊列
  this.evtList = [];
}
原型
EvtEmit.prototype = {
  constructor: EvtEmit,
  // 訂閱事件(監(jiān)聽)
  on(emitName, handler) {
    // console.debug(`EvtEmit -- on: ${emitName}`);
    if (!emitName) return;
    if (!this.evtList.some(evt => evt.emitName === emitName)) {
      this.evtList.push({
        emitName, // 事件名稱
        handler,
        once: emitName === "error" ");true : false
      });
    }
  },
  // 訂閱事件(一次性
  once(emitName, handler) {
    if (!emitName) return;
    if (!this.evtList.some(evt => evt.emitName === emitName)) {
      this.evtList.push({
        emitName, // 事件名稱
        handler,
        once: true
      });
    }
  },
  // 發(fā)布事件(觸發(fā))
  emit(emitName, ...param) {
    // console.debug(`EvtEmit -- emit: ${emitName}`);
    if (!emitName) return;
    let evtThis = this.evtList.find(evt => evt.emitName === emitName);
    if (!evtThis) {
      if (emitName !== "error") {
        console.warn(`請先使用監(jiān)聽on("${emitName}", callback),再emit("${emitName}")!`);
      }
      return;
    }
    // 一次性訂閱
    if (evtThis.once) this.off(emitName);

    // 監(jiān)聽[emitName]回調(diào)的錯誤
    try {
      evtThis.handler(...param);
    }
    catch (err) {
      // 不使用 on("error", callback)監(jiān)聽時,打印錯誤
      if (!this.evtList.some(evt => evt.emitName === "error")) {
        console.error(`on("${emitName}", callback) -> callback Error: ${err}`);
      }

      // 錯誤觸發(fā),可以使用 on("error", callback)監(jiān)聽
      this.emit("error", {
        emitName,
        err
      });
    }
  },
  // 注銷事件訂閱
  off(emitName, callback = null) {
    let arr = this.evtList.filter(evt => evt.emitName !== emitName);
    this.evtList = arr;
    arr = null;
    if (callback) {
      callback.call(this, emitName);
    }
  }
};

使用

同正常的發(fā)布訂閱一樣,先訂閱(on)再發(fā)布(emit);

const evt = new EvtEmit();

// 監(jiān)聽"run"事件
// 執(zhí)行1次on監(jiān)聽,10次回調(diào)函數(shù)
evt.on("run", res => {
  console.log("res: ", res);
  // 注銷監(jiān)聽,以下 emit 之后將不再觸發(fā) on;注釋之后將無限調(diào)用
  if (--res < 1) {
    evt.off("run", emitName => {
      console.log(`on("${emitName}")已注銷!`);
    });
    return;
  }

  evt.emit("run", res);
});

evt.emit("run", 10);

輸出

錯誤監(jiān)聽

try/catch執(zhí)行監(jiān)聽的回調(diào)函數(shù),捕獲錯誤然后觸發(fā)emit("error", err),通過on("error", callback)監(jiān)聽錯誤;

為什么需要 try/catch");
不使用try/catch捕獲錯誤的話,一旦發(fā)生錯誤,進(jìn)程就掛了,這時,后續(xù)不需要依賴你這次操作結(jié)果的 程序就會跑不下去了!!!(如下 打印 "after go",如果沒有try/catch,那么他就不會被打印);
這在服務(wù)端用的比較多,想象一下,一個接口因為某次調(diào)用的參數(shù)不合法或者其他因素,導(dǎo)致程序中斷而影響到后續(xù)使用,可能產(chǎn)生‘事故’!

try/catch 包裹回調(diào)函數(shù)的執(zhí)行
// 發(fā)布事件(觸發(fā))
  emit(emitName, ...param) {
    // console.debug(`EvtEmit -- emit: ${emitName}`);
    if (!emitName) return;
    let evtThis = this.evtList.find(evt => evt.emitName === emitName);
    if (!evtThis) {
      if (emitName !== "error") {
        console.warn(`請先使用監(jiān)聽on("${emitName}", callback),再emit("${emitName}")!`);
      }
      return;
    }
    // 一次性訂閱
    if (evtThis.once) this.off(emitName);

    // 監(jiān)聽[emitName]回調(diào)的錯誤
    try {
      evtThis.handler(...param);
    }
    catch (err) {
      // 不使用 on("error", callback)監(jiān)聽時,打印錯誤
      if (!this.evtList.some(evt => evt.emitName === "error")) {
        console.error(`on("${emitName}", callback) -> callback Error: ${err}`);
      }

      // 錯誤觸發(fā),可以使用 on("error", callback)監(jiān)聽
      this.emit("error", {
        emitName,
        err
      });
    }
  },
錯誤捕獲:
evt.on("error", ({ emitName, err }) => {
  console.error(`on("${emitName}", callback) -> callback Error: ${err}`);
})

evt.on("go", res => {
  err; // 錯誤會被 try/catch 捕獲
  console.log("res: ", res);
});

evt.emit("go", "go");
console.log("after go"); // 沒有 try/catch 的話,不會執(zhí)行
全部代碼 EvtEmit_callback.js:
// EvtEmit_callback.js
// 發(fā)布訂閱,回調(diào)函數(shù)版本
function EvtEmit() {
  // 事件參數(shù)隊列
  this.evtList = [];
}
EvtEmit.prototype = {
  constructor: EvtEmit,
  // 訂閱事件(監(jiān)聽)
  on(emitName, handler) {
    // console.debug(`EvtEmit -- on: ${emitName}`);
    if (!emitName) return;
    if (!this.evtList.some(evt => evt.emitName === emitName)) {
      this.evtList.push({
        emitName, // 事件名稱
        handler,
        once: emitName === "error" ");true : false
      });
    }
  },
  // 訂閱事件(一次性
  once(emitName, handler) {
    if (!emitName) return;
    if (!this.evtList.some(evt => evt.emitName === emitName)) {
      this.evtList.push({
        emitName, // 事件名稱
        handler,
        once: true
      });
    }
  },
  // 發(fā)布事件(觸發(fā))
  emit(emitName, ...param) {
    // console.debug(`EvtEmit -- emit: ${emitName}`);
    if (!emitName) return;
    let evtThis = this.evtList.find(evt => evt.emitName === emitName);
    if (!evtThis) {
      if (emitName !== "error") {
        console.warn(`請先使用監(jiān)聽on("${emitName}", callback),再emit("${emitName}")!`);
      }
      return;
    }
    // 一次性訂閱
    if (evtThis.once) this.off(emitName);

    // 監(jiān)聽[emitName]回調(diào)的錯誤
    try {
      evtThis.handler(...param);
    }
    catch (err) {
      // 不使用 on("error", callback)監(jiān)聽時,打印錯誤
      if (!this.evtList.some(evt => evt.emitName === "error")) {
        console.error(`on("${emitName}", callback) -> callback Error: ${err}`);
      }

      // 錯誤觸發(fā),可以使用 on("error", callback)監(jiān)聽
      this.emit("error", {
        emitName,
        err
      });
    }
  },
  // 注銷事件訂閱
  off(emitName, callback = null) {
    let arr = this.evtList.filter(evt => evt.emitName !== emitName);
    this.evtList = arr;
    arr = null;
    if (callback) {
      callback.call(this, emitName);
    }
  }
};

const evt = new EvtEmit();

// 執(zhí)行1次on監(jiān)聽,10次回調(diào)函數(shù)
evt.on("run", res => {
  console.log("res: ", res);
  // 注銷監(jiān)聽,以下 emit 之后將不再觸發(fā) on;注釋之后將無限調(diào)用
  if (--res < 1) {
    evt.off("run", emitName => {
      console.log(`on("${emitName}")已注銷!`);
    });
    return;
  }

  evt.emit("run", res);
});

evt.emit("run", 10);


// evt.on("error", ({ emitName, err }) => {
//   console.error(`on("${emitName}", callback) -> callback Error: ${err}`);
// })

// evt.on("go", res => {
//   err; // 錯誤會被 try/catch 捕獲
//   console.log("res: ", res);
// });

// evt.emit("go", "go");
// console.log("after go"); // 沒有 try/catch 的話,不會執(zhí)行

參考

    js設(shè)計模式之發(fā)布/訂閱模式模式

    events(事件觸發(fā)器)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/6776.html

相關(guān)文章

  • JS設(shè)計模式Obeserver(觀察者)模式、Publish/Subscribe(發(fā)布/訂閱模式

    摘要:觀察者模式定義設(shè)計模式中對的定義一個對象稱為維持一系列依賴于它觀察者的對象,將有關(guān)狀態(tài)的任何變更自動通知給它們。如圖模式比較觀察者模式則多了一個類似于話題調(diào)度中心的流程,發(fā)布者和訂閱者解耦。 Obeserver(觀察者)模式 定義 《js設(shè)計模式》中對Observer的定義:一個對象(稱為subject)維持一系列依賴于它(觀察者)的對象,將有關(guān)狀態(tài)的任何變更自動通知給它們。 《設(shè)計模...

    荊兆峰 評論0 收藏0
  • JavaScript設(shè)計模式發(fā)布-訂閱模式(觀察者模式)-Part1

    摘要:設(shè)計模式與開發(fā)實踐讀書筆記。發(fā)布訂閱模式又叫觀察者模式,它定義了對象之間的一種一對多的依賴關(guān)系。附設(shè)計模式之發(fā)布訂閱模式觀察者模式數(shù)據(jù)結(jié)構(gòu)和算法系列棧隊列優(yōu)先隊列循環(huán)隊列設(shè)計模式系列設(shè)計模式之策略模式 《JavaScript設(shè)計模式與開發(fā)實踐》讀書筆記。 發(fā)布-訂閱模式又叫觀察者模式,它定義了對象之間的一種一對多的依賴關(guān)系。當(dāng)一個對象的狀態(tài)發(fā)生改變時,所有依賴它的對象都將得到通知。 例...

    muzhuyu 評論0 收藏0
  • JavaScript設(shè)計模式發(fā)布-訂閱模式(觀察者模式)-Part2

    摘要:設(shè)計模式與開發(fā)實踐讀書筆記。看此文章前,建議先看設(shè)計模式之發(fā)布訂閱模式觀察者模式在中,已經(jīng)介紹了什么是發(fā)布訂閱模式,同時,也實現(xiàn)了發(fā)布訂閱模式。 《JavaScript設(shè)計模式與開發(fā)實踐》讀書筆記。 看此文章前,建議先看JavaScript設(shè)計模式之發(fā)布-訂閱模式(觀察者模式)-Part1 在Part1中,已經(jīng)介紹了什么是發(fā)布-訂閱模式,同時,也實現(xiàn)了發(fā)布-訂閱模式。但是,就Part1...

    Charlie_Jade 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<