Tapable 所提供的 plugin
方法類似於 addEventListen
監聽事件,apply
方法類似於事件觸發函式 trigger
plugin
Tapable.prototype.plugin = function plugin(name, fn) {
// 將函式注入多個事件流中
if (Array.isArray(name)) {
name.forEach(function(name) {
this.plugin(name, fn);
}, this);
return;
}
// 如果不存在該事件流 新建並將函式插入
if (!this._plugins[name]) this._plugins[name] = [fn];
// 存在就新增執行函式
else this._plugins[name].push(fn);
};複製程式碼
hasPlugins
Tapable.prototype.hasPlugins = function hasPlugins(name) {
// 嘗試獲取對應事件流
var plugins = this._plugins[name];
// 存在事件流且有可執行函式
return plugins && plugins.length > 0;
};複製程式碼
apply
Tapable.prototype.apply = function apply(...fns) {
// 遍歷所有引數並執行
for (var i = 0; i < fns.length; i++) {
fns[i].apply(this);
}
};複製程式碼
該函式並不直接關聯於_plugins物件,而是按照引數傳入順序依次執行。
applyPlugins
依次遍歷指定name的事件流,不同名字的函式可接受引數數量不一樣。
// 不接受傳參
Tapable.prototype.applyPlugins0 = function applyPlugins0(name) {
var plugins = this._plugins[name];
if (!plugins) return;
for (var i = 0; i < plugins.length; i++)
plugins[i].call(this);
};
// 接受一個引數
Tapable.prototype.applyPlugins1 = function applyPlugins1(name, param) {
var plugins = this._plugins[name];
if (!plugins) return;
for (var i = 0; i < plugins.length; i++)
plugins[i].call(this, param);
};
...
// 接受五個引數
Tapable.prototype.applyPlugins5 = function applyPlugins5(name, param1, param2) {
var plugins = this._plugins[name];
if (!plugins) return;
for (var i = 0; i < plugins.length; i++)
plugins[i].call(this, param1, param2, param3, param4, param5);
};
// 接受任意數量引數
Tapable.prototype.applyPlugins = function applyPlugins(name) {
var args = Array.prototype.slice.call(arguments, 1); if (!this._plugins[name]) return;
// var args = Array.prototype.slice.call(arguments, 1);
var plugins = this._plugins[name];
for (var i = 0; i < plugins.length; i++)
plugins[i].apply(this, args);
};複製程式碼
applyPluginsWaterfall
事件流執行過程中,每一次執行的返回值會作為下一次的引數(僅限於第一個引數)。
Tapable.prototype.applyPluginsWaterfall0 = function applyPluginsWaterfall0(name, init) {
var plugins = this._plugins[name];
if (!plugins) return init;
var current = init;
for (var i = 0; i < plugins.length; i++)
current = plugins[i].call(this, current);
return current;
};
// ...1
// ...
// ...5
Tapable.prototype.applyPluginsWaterfall = function applyPluginsWaterfall(name, init) { if(!this._plugins[name]) return init; var args = Array.prototype.slice.call(arguments, 1); var plugins = this._plugins[name]; var current = init; for(var i = 0; i < plugins.length; i++) { args[0] = current; current = plugins[i].apply(this, args); } return current;};複製程式碼
applyPluginsBailResult
事件流執行過程中,返回第一個不是undefined的值,後續函式不執行。
Tapable.prototype.applyPluginsBailResult = function applyPluginsBailResult(name, ...args) {
if (!this._plugins[name]) return;
// var args = Array.prototype.slice.call(arguments, 1);
var plugins = this._plugins[name];
for (var i = 0; i < plugins.length; i++) {
var result = plugins[i].apply(this, args);
if (typeof result !== "undefined") {
return result;
}
}
};
// 1,2,3,4,5複製程式碼
applyPluginsAsync
Tapable.prototype.applyPluginsAsync = function applyPluginsAsyncSeries(name) { var args = Array.prototype.slice.call(arguments, 1); var callback = args.pop(); var plugins = this._plugins[name]; if(!plugins || plugins.length === 0) return callback(); var i = 0; var _this = this; args.push(copyProperties(callback, function next(err) { if(err) return callback(err); i++; if(i >= plugins.length) { return callback(); } plugins[i].apply(_this, args); })); plugins[0].apply(this, args);};複製程式碼