tapable

221 阅读2分钟

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);};