Tapable

Tapable 的使用

Tapable 本身不能使用鲁森,只能使用從它導(dǎo)出的 Hook

const {
  SyncHook,
  SyncBailHook,
  SyncWaterfallHook,
  SyncLoopHook,
  AsyncSeriesHook,
  AsyncSeriesBailHook,
  AsyncSeriesWaterfallHook,
  AsyncParallelHook,
  AsyncParallelBailHook,
} = require('tapable');

Hook 可以按照兩種標(biāo)準(zhǔn)來分類

  1. 事件回調(diào)的運(yùn)行邏輯:
  • Basic:基本類型,按順序執(zhí)行注冊(cè)的回調(diào)
  • Bail:保險(xiǎn)類型振惰,當(dāng)一個(gè)事件回調(diào)的返回值不為 undefined 時(shí)刀森,停止后面的回調(diào)執(zhí)行
  • Waterfall:瀑布類型,如果當(dāng)前事件回調(diào)的返回值不為 undefined报账,那么返回值就作為下一個(gè)回調(diào)的第一個(gè)參數(shù)
  • Loop:循環(huán)類型,如果當(dāng)前事件回調(diào)的返回值不為 undefined埠偿,回到第一個(gè)事件注冊(cè)的回調(diào)執(zhí)行透罢,直到所有的回調(diào)都返回 undefined(沒有返回)
  1. 觸發(fā)事件的方式:
  • Sync:以 sync 開頭的 hook,同步的執(zhí)行注冊(cè)的事件冠蒋;只能使用 tap 方法注冊(cè)羽圃,使用 tapAsync 或 tapPromise 注冊(cè)會(huì)報(bào)錯(cuò)
  • AsyncSerise:以 asyncSerise 開頭的 hook,按順序的執(zhí)行事件回調(diào)抖剿,如果回調(diào)是異步的朽寞,等異步執(zhí)行完成才會(huì)執(zhí)行下一個(gè)事件回調(diào);可以使用 tap斩郎、tapAsync脑融、tapPromise 注冊(cè)事件回調(diào);不能使用 call() 方法觸發(fā)回調(diào)
  • AsyncParalle:以 asyncParalle 開頭的 hook缩宜,并行的執(zhí)行所有的事件回調(diào)

Sync hook

// 實(shí)例化 Hook
const { SyncHook } = require('tapable');
// 實(shí)例化鉤子類時(shí)傳入的數(shù)組肘迎,實(shí)際上只用上了數(shù)組的長(zhǎng)度,名稱是為了便于維護(hù)
const hook = new SyncHook(['name']);

// 事件注冊(cè)
hook.tap('first', (name) => {
  console.log('first ', name);
});
// 第一個(gè)參數(shù)可以是事件回調(diào)的名字锻煌,也可以是配置對(duì)象
hook.tap({name: 'second'}, (name) => {
    console.log('second ', name);
});

//觸發(fā)
hook.call('jack'); // 對(duì)應(yīng) sync hook

/**
 * Console output:
 * 
 * first jack
 * second jack
 */

AsyncSerise hook

const { AsyncSeriesHook } = require('tapable');
const hook = new AsyncSeriesHook(['name']);

// 事件回調(diào)接收到 callback
hook.tapAsync('first', (name, callback) => {
  console.log('first', name, callback);
  callback();
});

// 最后一個(gè)傳入?yún)?shù)是回調(diào)函數(shù)
hook.callAsync('callAsync', (error) => {
    console.log('callAsync', error);
});

/**
 * Console output:
 * 
 * first callAsync [Function]
 * callAsync undefined
 */

callAsync 的第二個(gè)參數(shù):錯(cuò)誤回調(diào)callback

  • 事件回調(diào)中必須調(diào)用 callback妓布,才能執(zhí)行下一個(gè)事件回調(diào)
  • 調(diào)用 callback 時(shí)不傳入?yún)?shù)時(shí)執(zhí)行下一個(gè)回調(diào),傳入第一個(gè)參數(shù)代表有錯(cuò)誤發(fā)生宋梧,接下來會(huì)執(zhí)行觸發(fā)時(shí)的回調(diào)

Async hook 使用 tapPromise 注冊(cè)

const { AsyncSeriesHook } = require('tapable');
const hook = new AsyncSeriesHook(['name']);

hook.tapPromise('first', (name) => {
  console.log('first', name);

  return Promise.resolve('first');
});

hook.tapPromise('second', (name) => {
  console.log('second', name);

  return Promise.resolve('second');
});

const promise = hook.promise('promise');

console.log(promise);

promise.then(value => {
  // value 是 undefined匣沼,不會(huì)接收到事件回調(diào)中傳入的值
  console.log('value', value);
}, reason => {
  // 事件回調(diào)返回的 Promise 對(duì)象狀態(tài)是 Rejected
  // reason 會(huì)有事件回調(diào)中傳入的錯(cuò)誤信息
  console.log('reason', reason);
});

/**
 * Console output:
 * 
 * first promise
 * Promise { <pending> } // 同步代碼
 * second promise  // tapPromise 是微任務(wù),所以會(huì)在同步代碼后執(zhí)行
 * value undefined
 */

promise 執(zhí)行之后會(huì)返回一個(gè) Promise 對(duì)象捂龄。在使用 tapPromise 注冊(cè)事件回調(diào)時(shí)释涛,事件回調(diào)必須返回一個(gè) Promise 對(duì)象,否則會(huì)報(bào)錯(cuò)倦沧,這是為了確保事件回調(diào)能夠按照順序執(zhí)行枢贿。
攔截器
我們可以給鉤子類添加攔截器,這樣就能對(duì)事件回調(diào)的注冊(cè)刀脏、調(diào)用以及事件的觸發(fā)進(jìn)行監(jiān)聽

const { SyncHook } = require('tapable');
const hook = new SyncHook();

hook.intercept({
  // 注冊(cè)時(shí)執(zhí)行
  register(tap) {
    console.log('register', tap);
    return tap;
  },
  // 觸發(fā)事件時(shí)執(zhí)行
  call(...args) {
    console.log('call', args);
  },
  // 在 call 攔截器之后執(zhí)行
  loop(...args) {
    console.log('loop', args);
  },
  // 事件回調(diào)調(diào)用前執(zhí)行
  tap(tap) {
    console.log('tap', tap);
  },
});

參考鏈接:https://zhuanlan.zhihu.com/p/100974318

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末局荚,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耀态,老刑警劉巖轮傍,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異首装,居然都是意外死亡创夜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門仙逻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來驰吓,“玉大人,你說我怎么就攤上這事系奉∶史。” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵缺亮,是天一觀的道長(zhǎng)翁涤。 經(jīng)常有香客問我,道長(zhǎng)萌踱,這世上最難降的妖魔是什么葵礼? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮并鸵,結(jié)果婚禮上鸳粉,老公的妹妹穿的比我還像新娘。我一直安慰自己园担,他們只是感情好赁严,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著粉铐,像睡著了一般疼约。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蝙泼,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天程剥,我揣著相機(jī)與錄音,去河邊找鬼汤踏。 笑死织鲸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的溪胶。 我是一名探鬼主播搂擦,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼哗脖!你這毒婦竟也來了瀑踢?” 一聲冷哼從身側(cè)響起扳还,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎橱夭,沒想到半個(gè)月后氨距,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡棘劣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年俏让,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茬暇。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡首昔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出糙俗,到底是詐尸還是另有隱情勒奇,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布臼节,位于F島的核電站,受9級(jí)特大地震影響珊皿,放射性物質(zhì)發(fā)生泄漏网缝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一蟋定、第九天 我趴在偏房一處隱蔽的房頂上張望粉臊。 院中可真熱鬧,春花似錦驶兜、人聲如沸扼仲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)屠凶。三九已至,卻和暖如春肆资,著一層夾襖步出監(jiān)牢的瞬間矗愧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工郑原, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留唉韭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓犯犁,卻偏偏與公主長(zhǎng)得像属愤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子酸役,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容