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

資訊專欄INFORMATION COLUMN

js中的一對多 - 訂閱發(fā)布模式

Cobub / 2660人閱讀

摘要:解決命名空間問題暫不管,刪除訂閱問題這個(gè)用處不大目前我們先著手解決這個(gè)問題對應(yīng)的消息么有被人訂閱沒有傳入具體的回調(diào)函數(shù)表示取消對應(yīng)的所有訂閱反向遍歷刪除訂閱回調(diào)函數(shù)這個(gè)對象,能夠解決大部分事件模擬的問題。

訂閱發(fā)布模式如果按數(shù)學(xué)翻譯其實(shí)就是.一對多的映射關(guān)系.怎么解釋呢? 就是一個(gè)開關(guān),同時(shí)并聯(lián)幾個(gè)燈泡(在不同房間),觸發(fā)的時(shí)候,幾個(gè)燈泡都會(huì)得到指令,然后執(zhí)行發(fā)光的行為。

訂閱發(fā)布模式

這種模式在js里面有這天然的優(yōu)勢,因?yàn)閖s本身就是事件驅(qū)動(dòng)型語言。比如,頁面上有一個(gè)button, 你點(diǎn)擊一下就會(huì)觸發(fā)上面的click事件,而此時(shí)有一部分程序正在監(jiān)聽這個(gè)事件,隨之觸發(fā)相關(guān)的處理程序.

var button = $("#button");
button.on("click",function(){
    console.log("I am pressing the button");
});

事實(shí)上,我們也早就熟悉這個(gè)模式了,只是不知道這叫什么(訂閱發(fā)布模式 又名 觀察者模式).
這個(gè)模式最大的一個(gè)好處就在于,能夠解耦回調(diào)函數(shù),讓你的程序看起來更美觀(雖然現(xiàn)在有Promise和Deferred幫忙,但是不徹底)。

訂閱發(fā)布模式內(nèi)涵

說了點(diǎn)理論,來些干貨。(以下將訂閱發(fā)布模式簡稱為觀察者模式).
觀察者模式無非就兩個(gè)部分,一個(gè)訂閱(監(jiān)聽程序),一個(gè)發(fā)布(觸發(fā)事件).而他們中間的鏈接樞紐就是事件。 通常來說,我們可以自定義一個(gè)觀察者模式--使用自定義事件.
(由于IE過于SB,我就不想說他的事了,下面這些適用于chrome, iE9+,ff等其他現(xiàn)代瀏覽器中)

 // Create the event.  //創(chuàng)建一個(gè)事件
var event = document.createEvent("Event"); //Event是自定義的事件名

// Define that the event name is "build".
event.initEvent("build", true, true);  //這里是初始化事件,  //就是些參數(shù)而已.

// Listen for the event.
elem.addEventListener("build", function (e) {    //給事件添加監(jiān)聽
  // e.target matches elem
}, false);

// target can be any Element or other EventTarget.
elem.dispatchEvent(event);    //觸發(fā)事件

大致就是這幾個(gè)步驟,由于這樣寫,太非人道了。所以這里映入jquery的trigger觸發(fā)方式(大哥就是大哥~)
在jquery的事件處理中,幾個(gè)基本和事件相關(guān)的API需要熟悉。一個(gè)是on,一個(gè)是trigger.

$(".ele").on("click",function(){
    console.log("clicking");
});
$(".ele").trigger("click");

這是一個(gè)基本的使用,使用trigger來觸發(fā)事件.
但是誰尼瑪無聊到連click自己手動(dòng)觸發(fā)啊,這個(gè)例子只是講解。現(xiàn)在說一下精華-自定義事件.
在jquery里面,可以直接使用on來進(jìn)行自定義事件的模擬。

ele.on("stimulate",function(){  //訂閱一個(gè)事件
    ...do sth
});
ele.trigger("stimulate");  //發(fā)布一個(gè)事件

這里trigger只是起到一個(gè)開關(guān)的作用,那么我想要他變?yōu)橐粋€(gè)管道可以嗎?
absolutely!!!
在trigger里面還有第二個(gè)參數(shù)可以選擇,即[data]

$(document.body).on("stimulate",function(event,name1,name2){  //和節(jié)點(diǎn)有關(guān)的事件里,第一個(gè)參數(shù)永遠(yuǎn)是event
    console.log(name1,name2);  //"jimmy","sam"
});
$(document.body).trigger("stimulate",["jimmy","sam"]);

而且如果你自定義事件過多,起名也是件死人的事。所以牛逼的jq會(huì)幫你把命名空間處理好.

ele.on("stimulate.jimmy.sam",function(){  //使用"."鏈接
    ...do sth
});

他的作用域就是sam>jimmy>stimulate這樣一個(gè)關(guān)系.
詳情可以參考: Aron大神些的jquery事件解析。這里我直接把trigger的源碼貼出來吧.以供參考.
trigger源碼
其實(shí)上面的自定義事件的用法也非常有限,因?yàn)槿绻褂靡粋€(gè)節(jié)點(diǎn)作為載體的話,這樣的成本也太大了。所以一般在業(yè)內(nèi)已經(jīng)有成熟的自定義事件的插件了.
不過為了深入理解觀察者模式,我們一步一步來.(為了裝逼)

訂閱發(fā)布模式進(jìn)階

經(jīng)過上面的唐僧咒,大家也應(yīng)該差不多熟悉這個(gè)模式的一些關(guān)鍵部分。訂閱,發(fā)布,事件。
好,我們就這3個(gè)部分來自己模擬一個(gè)。

//摘自alloyTeam團(tuán)隊(duì)的曾探·著
var imitate = (function() {
    var imitate = {
        clientList: [],
        listen: function(key, fn) {
            if (!this.clientList[key]) {
                this.clientList[key] = [];
            }
            this.clientList[key].push(fn);
        },
        trigger: function() {
            var key = [].shift.call(arguments);
            var fns = this.clientList[key];

            // 如果沒有對應(yīng)的綁定消息
            if (!fns || fns.length === 0) {
                return false;
            }

            for (var i = 0, fn; fn = fns[i++];) {
                // arguments 是 trigger帶上的參數(shù)
                fn.apply(this, arguments);
            }
        }
    }
    return function() {
       return Object.create(imitate);
    }
})();
var eventModel = imitate();  //得到上面的對象
eventModel.listen("jimmy",function(){console.log("jimmy");});  //jimmy
eventModel.trigger("jimmy");

恩,這樣下來皆可以和重重的節(jié)點(diǎn)說拜拜了。直接使用imitate就可以進(jìn)行事件的模擬,而且超快.
當(dāng)然,這樣寫改進(jìn)的空間還是挺大的。解決命名空間問題(暫不管),刪除訂閱問題(這個(gè)用處不大)...目前我們先著手解決這個(gè)問題.

var Event = (function() {
    var clientList = {};
    var listen,
        trigger,
        remove;
    listen = function(key, fn) {
        if (!clientList[key]) {
            clientList[key] = [];
        }
        clientList[key].push(fn);
    };

    trigger = function() {
        var key = [].shift.call(arguments);
        var fns = clientList[key];

        if (!fns || fns.length === 0) {
            return false;
        }

        for (var i = 0, fn; fn = fns[i++];) {
            fn.apply(this, arguments);
        }
    };


    remove = function(key, fn) {
        var fns = clientList[key];

        // key對應(yīng)的消息么有被人訂閱
        if (!fns) {
            return false;
        }

        // 沒有傳入fn(具體的回調(diào)函數(shù)), 表示取消key對應(yīng)的所有訂閱
        if (!fn) {
            fns && (fns.length = 0);
        }
        else {
            // 反向遍歷
            for (var i = fns.length - 1; i >= 0; i--) {
                var _fn = fns[i];
                if (_fn === fn) {
                    // 刪除訂閱回調(diào)函數(shù)
                    fns.splice(i, 1);
                }
            }
        }
    };

    return {
        listen: listen,
        trigger: trigger,
        remove: remove
    }
}());

這個(gè)Event對象,能夠解決大部分事件模擬的問題。說了這么多,md,實(shí)例嘞。。。等等。馬上來

發(fā)布訂閱模式的實(shí)戰(zhàn)

如果大家寫過登錄框(異步登錄哈),應(yīng)該知道.登錄框和header的部分是完全不同的兩個(gè)部分。這個(gè)場景就很適合發(fā)布訂閱模式了。
看一下。如果沒有發(fā)布訂閱模式的代碼:

login.on("click",function(){
    var name = $(".username").val().trim;
    http.login(name)  //使用異步Deferred書寫
    .then(function(data){  //以下填寫亂七八糟的處理
        changeName();
        changeAvtar();
        changeStatus();
        ...
    })
});

使用發(fā)布訂閱模式

login.on("click",function(){
    var name = $(".username").val().trim;
    http.login(name)  //使用異步Deferred書寫
    .then(function(data){
        Event.trigger("login",data);  //發(fā)布我登錄成功的狀態(tài),并傳入?yún)?shù)
    })
});
var header = (function() {
    Event.listen("login", function(data) {
        header.changeAvator(data);
    })
    return {
        changeAvator: function(data) {
            ...換頭像
        }
    }
})();
var bar = (function() {
    Event.listen("login", function(data) {
        bar.changeName(data);
    })
    return {
        changeName: function(data) {
            ...換名字
        }
    }
})();

可以清楚的看到,如果你的登錄狀態(tài)改變了的話,會(huì)有一系列的訂閱程序發(fā)生.而且每個(gè)訂閱之間互不干擾,你可以隨便添加或者刪除訂閱,這都不會(huì)影響你的登錄的執(zhí)行邏輯. 當(dāng)然發(fā)布訂閱的使用肯定不會(huì)僅僅局限于,登錄狀態(tài)的改變。還可以應(yīng)用于,模塊間信息的傳遞,分頁頁面的渲染等。但是使用的時(shí)候,一定要慎重,因?yàn)槟阌嗛喌脑蕉啵琤ug的查找也會(huì)越復(fù)雜。所以,發(fā)布訂閱模式使用的時(shí)候,希望大家好好想一想,不要為了模式而去模式。

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

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

相關(guān)文章

  • js設(shè)計(jì)模式 --- 發(fā)布訂閱模式(觀察者模式)

    摘要:由主體和觀察者組成,主體負(fù)責(zé)發(fā)布事件,同時(shí)觀察者通過訂閱這些事件來觀察該主體。主體并不知道觀察者的任何事情,觀察者知道主體并能注冊事件的回調(diào)函數(shù)。總的來說,觀察者模式所做的工作就是在解耦,讓耦合的雙方都依賴于抽象,而不是依賴于具體。 發(fā)布訂閱模式 發(fā)布訂閱模式又叫觀察者模式(Publish/Subscribe),它定義了一種一對多的關(guān)系,讓多個(gè)觀察者對象同時(shí)監(jiān)聽某一個(gè)主題對象,這個(gè)主題...

    EasonTyler 評(píng)論0 收藏0
  • 觀察者模式的使用介紹

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

    ityouknow 評(píng)論0 收藏0
  • JS每日一題:設(shè)計(jì)模式-如何理解觀察者(發(fā)布訂閱)模式?

    摘要:期設(shè)計(jì)模式如何理解觀察者發(fā)布訂閱模式定義觀察者模式又叫發(fā)布訂閱模式,它定義了一種一對多的關(guān)系,讓多個(gè)觀察者對象同時(shí)監(jiān)聽某一個(gè)主題對象,這個(gè)主題對象的狀態(tài)發(fā)生變化時(shí)就會(huì)通知所有的觀察者對象,使得它們能夠自動(dòng)更新自己生活實(shí)例理解你今天去看一個(gè) 20190411期 設(shè)計(jì)模式-如何理解觀察者(發(fā)布訂閱)模式? 定義: 觀察者模式又叫發(fā)布訂閱模式(Publish/Subscribe),它定義了一...

    baishancloud 評(píng)論0 收藏0
  • js 觀察者

    摘要:觀察者模式機(jī)動(dòng)建立一種對象與對象之間的依賴關(guān)系,一個(gè)對象發(fā)生改變時(shí)將自動(dòng)通知其他對象,其他對象將相應(yīng)做出反應(yīng)。 觀察者模式模式簡介 觀察者模式(又被稱為發(fā)布-訂閱(Publish/Subscribe)模式,屬于行為型模式的一種,它定義了一種一對多的依賴關(guān)系,讓多個(gè)觀察者對象同時(shí)監(jiān)聽某一個(gè)主題對象。這個(gè)主題對象在狀態(tài)變化時(shí),會(huì)通知所有的觀察者對象,使他們能夠自動(dòng)更新自己。 觀察者模式機(jī)動(dòng)...

    missonce 評(píng)論0 收藏0
  • Java 設(shè)計(jì)模式 觀察者模式

    摘要:實(shí)際上,設(shè)計(jì)模式就是通過面向?qū)ο蟮奶匦裕瑢⑦@些角色解耦觀察者模式本質(zhì)上就是一種訂閱發(fā)布的模型,從邏輯上來說就是一對多的依賴關(guān)系。在添加一個(gè)觀察者時(shí),把被主題被觀察者對象以構(gòu)造函數(shù)的形式給傳入了觀察者。 每個(gè)角色都對應(yīng)這一個(gè)類,比如觀察者模式,觀察者對應(yīng)著觀察者類,被觀察者對應(yīng)著被觀察者類。實(shí)際上,設(shè)計(jì)模式就是通過面向?qū)ο蟮奶匦裕瑢⑦@些角色解耦 觀察者模式本質(zhì)上就是一種訂閱 / 發(fā)布的模...

    馬忠志 評(píng)論0 收藏0

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

0條評(píng)論

Cobub

|高級(jí)講師

TA的文章

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