成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

觀察者模式的使用介紹

ityouknow / 2312人閱讀

摘要:觀察者模式介紹觀察者模式又稱發(fā)布訂閱模式,它定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象發(fā)生改變的時(shí)候,所依賴它的對(duì)象都能得到通知。關(guān)于內(nèi)部的觀察者模式可以參數(shù)這篇文檔??偨Y(jié)總之,觀察者模式在中的使用是非常廣泛的。

javascript觀察者模式 介紹

觀察者模式又稱發(fā)布-訂閱模式,它定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象發(fā)生改變的時(shí)候,所依賴它的對(duì)象都能得到通知。例如:我們訂閱了一個(gè)欄目,當(dāng)欄目有新文章的時(shí)候,它會(huì)自動(dòng)通知所有訂閱它的人。

特點(diǎn)

發(fā)布 & 訂閱

一對(duì)多

優(yōu)點(diǎn)

低耦合,觀察者和觀察目標(biāo)都是抽象出來,容易擴(kuò)展和重用

觸發(fā)(通訊)機(jī)制,由觀察目標(biāo)通知所有觀察它的人

缺點(diǎn)

一個(gè)觀察目標(biāo)下可能存在很多的觀察者,那么當(dāng)觀察目標(biāo)需要通知所有觀察者的時(shí)候會(huì)花很多時(shí)間

觀察者和觀察目標(biāo)之間如果存在依賴的話,可能會(huì)發(fā)生循環(huán)調(diào)用,進(jìn)入死循環(huán)導(dǎo)致系統(tǒng)崩潰

觀察者模式?jīng)]有相應(yīng)的機(jī)制讓觀察者知道觀察目標(biāo)是如何發(fā)生變化,僅僅知道觀察目標(biāo)發(fā)生了變化

觀察目標(biāo)可能將一些無用的更新發(fā)送出去

簡(jiǎn)單例子

例子:A,B,C三個(gè)人都關(guān)注了某一個(gè)電臺(tái),當(dāng)電臺(tái)發(fā)布新內(nèi)容的時(shí)候通知A,B,C三個(gè)人。

構(gòu)思:具體的構(gòu)思中,我們可以知道電臺(tái)作為發(fā)布者,它有了新的內(nèi)容,需要向ABC這三個(gè)訂閱者推送他的最新的消息。那么我們就可以知道電臺(tái)這個(gè)發(fā)布者需要包含新的更新內(nèi)容以及有哪些訂閱者訂閱了它。

代碼實(shí)現(xiàn):
簡(jiǎn)單的代碼實(shí)現(xiàn):

class Radio {
  constructor() {
    this.state = 0;
    this.observers = [];
  }

  setState(state) {
    this.state = state;
    this.notifyingObservers();
  }

  addObserver(observer) {
    this.observers.push(observer);
  }

  notifyingObservers() {
    const state = this.state;
    this.observers.forEach(observer => {
      observer.update(state);
    });
  }
}

class People {
  constructor(name) {
    this.name = name;
  }

  update(content) {
    console.log(`我是${this.name},我接受到更新了,更新內(nèi)容:${content}`);
  }
}

// 創(chuàng)建訂閱者
const peopleA = new People("小A");
const peopleB = new People("小B");
const peopleC = new People("小C");

// 添加發(fā)布者
const radio = new Radio();

// 訂閱
radio.addObserver(peopleA);
radio.addObserver(peopleB);
radio.addObserver(peopleC);

// 發(fā)布者發(fā)布
radio.setState("十月份最熱歌單發(fā)布了");
radio.setState("十一月份最新原創(chuàng)歌單發(fā)布了");

解讀:

抽象了一個(gè)發(fā)布者(Radio),它有更新內(nèi)容(setState)、添加訂閱者(addObserver)、以及觸發(fā)所有訂閱者(notifyingObservers);

抽象了一個(gè)訂閱者(People),他有自己的個(gè)人信息(如:name),以及接受到通知后所需要執(zhí)行的動(dòng)作(updata);

當(dāng)我們每次更新消息的時(shí)候出發(fā)notifyingObservers方法,將所有的observersupdate都觸發(fā)了

當(dāng)然,實(shí)際上,我們上的每一個(gè)訂閱者都有這個(gè)update,當(dāng)這個(gè)update不滿足功能需求的時(shí)候,我們同樣可以將實(shí)例出來的訂閱者多帶帶設(shè)置update; 如:

  peopleA.update = function(content) {
    // 新代碼
  }

以上就是一個(gè)簡(jiǎn)單的觀察者模式的例子

場(chǎng)景延伸

網(wǎng)頁(yè)頁(yè)面事件

代碼案例:



解讀:可以理解成函數(shù)訂閱了$("#btn")的click事件,當(dāng)$("#btn")的click被我們點(diǎn)擊觸發(fā),函數(shù)收到觸發(fā)信息,并自執(zhí)行。 那么這個(gè)函數(shù)就是觀察者(訂閱者),$("#btn")的click事件就是觀察目標(biāo)(發(fā)布者)。

Promise

代碼案例:

function loadImage(url) {
  return new Promise(function(resolve, reject) {
    let image = document.createElement("img");
    image.onload = function () {
      resolve(image);
    }
    image.onerror = function () {
      reject("圖片加載失敗");
    }
    image.src = url;
  });
}
const src = "http://imgsrc.baidu.com/image/c0%3Dpixel_huitu%2C0%2C0%2C294%2C40/sign=ad13ee4af0f2b211f0238d0ea3f80054/2e2eb9389b504fc26849383ceedde71190ef6df1.jpg"
const img = loadImage(src);
img.then(function (img) {
  console.log("width", img.width);
  return img
}).then(function (img) {
  console.log("height", img.height);
});

解讀:promise的resolve是then的執(zhí)行者,當(dāng)promise的狀態(tài)發(fā)生改變后(resolve的時(shí)候狀態(tài)從”未完成“變?yōu)椤背晒Α?,一一執(zhí)行then下的方法,那么這些then可以說是promise的觀察者,當(dāng)這個(gè)promise被resolve的時(shí)候,所有的觀察得到了通知。

關(guān)于promise內(nèi)部的觀察者模式可以參數(shù)https://github.com/xieranmaya/blog/issues/3這篇文檔。

promise.then會(huì)把內(nèi)部的函數(shù)添加到一個(gè)callback的數(shù)組內(nèi),等異步執(zhí)行完成之后在進(jìn)行一次調(diào)用該函數(shù)。每一個(gè).then會(huì)返回一個(gè)新的promise。

js的事件觸發(fā)器(自定義事件)

代碼案例:

class EventEmitter() {
  constructor() {
    this.events = {};
  }

  // 訂閱事件
  on(type, listener) {
    if (!this.events) { this.events = Object.create(null); }

    if (this.events[type]) {
      this.events[type].push(listener)
    } else {
      this.events[type] = [listener];
    }
  }

  // 觸發(fā)執(zhí)行
  emit(type, ...args) {
    if (this.events[type]) {
      this.events[type].forEach(fn => fn.call(this, ...args));
    }
  }

  // 解綁
  off(type, listener) {
    id (this.events[type]) {
      this.events[type] = this.events[type].filter(fn => {
        return fn !== listener;
      });
    }
  }
}

const myEmitter = new EventEmitter();
myEmitter.on("log", function() {console.log("111111")});
myEmitter.emit("log");

解讀:這個(gè)就和第一個(gè)案例有點(diǎn)相似,我們?cè)趈q中見過這樣的頁(yè)面事件寫法:

$("id").on("click", function() {
  // 事件代碼
});

這個(gè)就是一種事件觸發(fā)器,在nodejs里面大量采用了事件觸發(fā)器的方法。詳情可以去看nodejs里面的EventEmitter方法,就可以大體理解他的機(jī)制了。
同理,我們也可以明白react里面的生命周期等mvvm框架,里面大量采用了觀察者模式。它們都是定義了一個(gè)個(gè)鉤子,等狀態(tài)達(dá)到的時(shí)候我就觸發(fā)相對(duì)應(yīng)的鉤子,執(zhí)行相對(duì)應(yīng)的代碼。

總結(jié)

總之,觀察者模式在javascript中的使用是非常廣泛的。其低耦合的特點(diǎn)方便在多人開發(fā)的復(fù)雜項(xiàng)目中,能提高效率,使代碼的維護(hù)性大大提升。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99005.html

相關(guān)文章

  • RxJava系列二(基本概念及使用介紹

    摘要:作用默認(rèn)的,直接在當(dāng)前線程運(yùn)行總是開啟一個(gè)新線程用于密集型任務(wù),如異步阻塞操作,這個(gè)調(diào)度器的線程池會(huì)根據(jù)需要增長(zhǎng)對(duì)于普通的計(jì)算任務(wù),請(qǐng)使用默認(rèn)是一個(gè),很像一個(gè)有線程緩存的新線程調(diào)度器計(jì)算所使用的。這個(gè)使用的固定的線程池,大小為核數(shù)。 轉(zhuǎn)載請(qǐng)注明出處:https://zhuanlan.zhihu.com/p/20687307 RxJava系列1(簡(jiǎn)介) RxJava系列2(基本概念及使...

    Profeel 評(píng)論0 收藏0
  • php設(shè)計(jì)模式

    摘要:我們今天也來做一個(gè)萬能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識(shí)固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對(duì)容器接口對(duì)象進(jìn)行操作,第二類是返回一個(gè)容器接口對(duì)象,上節(jié)我們介紹了...

    Dionysus_go 評(píng)論0 收藏0
  • php設(shè)計(jì)模式

    摘要:我們今天也來做一個(gè)萬能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識(shí)固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對(duì)容器接口對(duì)象進(jìn)行操作,第二類是返回一個(gè)容器接口對(duì)象,上節(jié)我們介紹了...

    vspiders 評(píng)論0 收藏0
  • 察者模式到迭代器模式系統(tǒng)講解 RxJS Observable(一)

    摘要:是的縮寫,起源于,是一個(gè)基于可觀測(cè)數(shù)據(jù)流結(jié)合觀察者模式和迭代器模式的一種異步編程的應(yīng)用庫(kù)。是基于觀察者模式和迭代器模式以函數(shù)式編程思維來實(shí)現(xiàn)的。學(xué)習(xí)之前我們需要先了解觀察者模式和迭代器模式,還要對(duì)流的概念有所認(rèn)識(shí)。 RxJS 是 Reactive Extensions for JavaScript 的縮寫,起源于 Reactive Extensions,是一個(gè)基于可觀測(cè)數(shù)據(jù)流 Stre...

    notebin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

ityouknow

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<