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

資訊專欄INFORMATION COLUMN

發(fā)布訂閱管道化

widuu / 951人閱讀

摘要:發(fā)布訂閱作為一種常見(jiàn)的設(shè)計(jì)模式,在前端模塊化領(lǐng)域可以用來(lái)解決模塊循環(huán)依賴問(wèn)題。訂閱函數(shù)管道化上面的例子基本可以滿足需求了,但是有時(shí)候我們希望多個(gè)訂閱函數(shù)之間可以傳遞執(zhí)行結(jié)果,類似管道這種,上一個(gè)函數(shù)的輸出是下一個(gè)函數(shù)的輸入。

發(fā)布訂閱作為一種常見(jiàn)的設(shè)計(jì)模式,在前端模塊化領(lǐng)域可以用來(lái)解決模塊循環(huán)依賴問(wèn)題。

看一個(gè)簡(jiǎn)單的示例
// 消息中間件v1 
var msghub = (function() {
  var listener = [];
  return {
      on: function(type, cb, option) {
      listener[type] = listener[type] || [];
      option = option || {};
      listener[type].push({
          cb: cb,
          priority: option.priority || 0
      });
    },
    fire: function(type, dataObj) {
        if (listener[type]) {
          listener[type].sort((a, b) => a.priority - b.priority).forEach((item) => {
            item.cb.call(null, dataObj);
        });
      }
    }
  }
})();

以及消息中間件的使用模塊

// a.js
msghub.on("data", function(data) {
    console.log(data.val + 1); // 3
})
// b.js
msghub.on("data", function(data) {
    console.log(data.val + 2); // 4
})
// c.js
msghub.fire("data", {
    val: 2
});

當(dāng)c模塊觸發(fā)data事件的時(shí)候,a和b模塊的監(jiān)聽(tīng)函數(shù)都會(huì)被執(zhí)行并輸出相應(yīng)的結(jié)果。

訂閱函數(shù)管道化

上面的例子基本可以滿足需求了,但是有時(shí)候我們希望多個(gè)訂閱函數(shù)之間可以傳遞執(zhí)行結(jié)果,類似linux管道a.pipe(b).pipe(c)…這種,上一個(gè)函數(shù)的輸出是下一個(gè)函數(shù)的輸入。針對(duì)這種管道化需求我們對(duì)msghub的回調(diào)遍歷從forEach改為reduce方式,如下代碼所示

// 消息中間件v2 支持執(zhí)行結(jié)果傳遞
var msghub = (function() {
  var listener = [];
  option = option || {};
  return {
      on: function(type, cb, option) {
      listener[type] = listener[type] || [];
      listener[type].push({
          cb: cb,
          priority: option.priority || 0
      });
    },
    fire: function(type, dataObj) {
        if (listener[type]) {
          listener[type].sort((a, b) => b.priority - a.priority).reduce((pre, cur) => {
            let result = cur.cb.call(null, pre) || pre; // 如果一個(gè)訂閱函數(shù)沒(méi)有返回值則傳遞上上個(gè)訂閱函數(shù)的執(zhí)行結(jié)果,如果需要完全的管道化的話就把|| pre去掉即可
            return result;
        }, dataObj);
      }
    }
  }
})();

測(cè)試一下上面的msghub

// a.js
msghub.on("data", function(data) {
    console.log("module a get num:" + data.val); // 3
    return {
      val: ++data.val
    };
})
// b.js
msghub.on("data", function(data) {
  console.log("module b get num:" + data.val)
  return {
      val: data.val + 3
  }
})
// d.js
msghub.on("data", function(data) {
  console.log("module d get num:" + data.val);
})
// e.js
msghub.on("data", function(data) {
  console.log("module e get num:" + data.val);
})
// c.js
msghub.fire("data", {
    val: 2
});

使用改良后的msghub的話

    // a.js
    msghub.on("data", function(data) {
        console.log("module a get num:" + data.val); // 3
        return {
          val: ++data.val
        };
    })
    // b.js
    msghub.on("data", function(data) {
        console.log("module b get num:" + data.val)
        return {
            val: data.val + 3
        }
    })
    // d.js
    msghub.on("data", function(data) {
      console.log("module d get num:" + data.val);
    })
    // e.js
    msghub.on("data", function(data) {
      console.log("module e get num:" + data.val);
    })
    // c.js
    msghub.fire("data", {
        val: 2
    });

最終打印輸出如下信息:

module a get num:2
module b get num:3
module d get num:6
module e get num:6
訂閱函數(shù)支持異步

上面的例子中有一個(gè)問(wèn)題就是訂閱函數(shù)必須是同步代碼,如果a.js包含下述異步代碼的話就會(huì)出問(wèn)題

// a.js
msghub.on("data", function(data) {
  console.log("module a get num:" + data.val); // 3
  return new Promise(function(resolve, reject) {
    setTimeout(() => {
      resolve({
        val: ++data.val
      })
    }, 1000);
  });
})

針對(duì)可能同步可能異步的情況我們需要進(jìn)一步改良msghub來(lái)支持,該請(qǐng)asyn和await出場(chǎng)了

// 消息中間件v3 支持異步管道化
var msghub = (function() {
  var listener = [];
  return {
    on: function(type, cb, option) {
      listener[type] = listener[type] || [];
      option = option || {};
      listener[type].push({
        cb: cb,
        priority: option.priority || 0
      });
    },
    fire: function(type, dataObj) {
      if (listener[type]) {
        let listenerArr = listener[type].sort((a, b) => b.priority - a.priority);
        (async function iter() {
          let val = dataObj;
          for (const item of listenerArr) {
            val = await item.cb.call(null, val);
          }
        })();
      }
    }
  }
})();

注意: 上述代碼可以在node環(huán)境做測(cè)試,如果需要在瀏覽器中運(yùn)行的話,需要對(duì)for of和async await進(jìn)行babel編譯

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

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

相關(guān)文章

  • 學(xué)習(xí)這些設(shè)計(jì)模式,讓你寫(xiě)出更優(yōu)雅的代碼

    摘要:寫(xiě)代碼容易,寫(xiě)出優(yōu)雅的代碼難,寫(xiě)易于維護(hù)的容易擴(kuò)展的結(jié)構(gòu)清晰的代碼應(yīng)該是每位開(kāi)發(fā)者努力的目標(biāo),而學(xué)習(xí)設(shè)計(jì)模式,合理的的使用能讓我們離這個(gè)目標(biāo)更進(jìn)一步。 寫(xiě)代碼容易,寫(xiě)出優(yōu)雅的代碼難,寫(xiě)易于維護(hù)的、容易擴(kuò)展的、結(jié)構(gòu)清晰的代碼應(yīng)該是每位開(kāi)發(fā)者努力的目標(biāo),而學(xué)習(xí)設(shè)計(jì)模式,合理的的使用能讓我們離這個(gè)目標(biāo)更進(jìn)一步。最近看了《Javascript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐》這本書(shū),一言以蔽之,真不錯(cuò)的一本...

    songjz 評(píng)論0 收藏0
  • 學(xué)習(xí)這些設(shè)計(jì)模式,讓你寫(xiě)出更優(yōu)雅的代碼

    摘要:寫(xiě)代碼容易,寫(xiě)出優(yōu)雅的代碼難,寫(xiě)易于維護(hù)的容易擴(kuò)展的結(jié)構(gòu)清晰的代碼應(yīng)該是每位開(kāi)發(fā)者努力的目標(biāo),而學(xué)習(xí)設(shè)計(jì)模式,合理的的使用能讓我們離這個(gè)目標(biāo)更進(jìn)一步。 寫(xiě)代碼容易,寫(xiě)出優(yōu)雅的代碼難,寫(xiě)易于維護(hù)的、容易擴(kuò)展的、結(jié)構(gòu)清晰的代碼應(yīng)該是每位開(kāi)發(fā)者努力的目標(biāo),而學(xué)習(xí)設(shè)計(jì)模式,合理的的使用能讓我們離這個(gè)目標(biāo)更進(jìn)一步。最近看了《Javascript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐》這本書(shū),一言以蔽之,真不錯(cuò)的一本...

    用戶84 評(píng)論0 收藏0

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

0條評(píng)論

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