SOURCE

console 命令行工具 X clear

                    
>
console
function Tapable() {
    this._plugins = {};
}
function copyProperties(from, to) {
    for (var key in from)
        to[key] = from[key];
    return to;
}
//同步串行钩子
Tapable.prototype.applyPlugins = function applyPlugins(name) {
    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);
};
//同步瀑布钩子
Tapable.prototype.applyPluginsWaterfall = function applyPluginsWaterfall(name, init) {
    if (!this._plugins[name]) return init;
    var args = Array.prototype.slice.call(arguments, 1);
    console.info(args)
    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;
};
//同步竞争钩子
Tapable.prototype.applyPluginsBailResult = function applyPluginsBailResult(name) {
    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;
        }
    }
};
//异步串行钩子(主动调用cb通知下个插件执行)
Tapable.prototype.applyPluginsAsyncSeries = 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);
};
//类似于promise.all
Tapable.prototype.applyPluginsParallel = function applyPluginsParallel(name) {
    var args = Array.prototype.slice.call(arguments, 1);
    var callback = args.pop();
    if (!this._plugins[name] || this._plugins[name].length === 0) return callback();
    var plugins = this._plugins[name];
    var remaining = plugins.length;
    args.push(copyProperties(callback, function (err) {
        if (remaining < 0) return; // ignore
        if (err) {
            remaining = -1;
            return callback(err);
        }
        remaining--;
        if (remaining === 0) {
            return callback();
        }
    }));
    for (var i = 0; i < plugins.length; i++) {
        plugins[i].apply(this, args);
        if (remaining < 0) return;
    }
};
Tapable.prototype.applyPluginsAsyncSeriesBailResult = function applyPluginsAsyncSeriesBailResult(name) {
    var args = Array.prototype.slice.call(arguments, 1);
    var callback = args.pop();
    if (!this._plugins[name] || this._plugins[name].length === 0) return callback();
    var plugins = this._plugins[name];
    var i = 0;
    var _this = this;
    args.push(copyProperties(callback, function next() {
        if (arguments.length > 0) return callback.apply(null, arguments);
        i++;
        if (i >= plugins.length) {
            return callback();
        }
        plugins[i].apply(_this, args);
    }));
    plugins[0].apply(this, args);
};
const wait = (name, delay) => function (a, b, cb) {
    setTimeout(() => {
        console.log(name, a, b);
        cb(null, 'err');
    }, delay)
}
const call = (name) => function (a, b, cb) {
    console.log(name, a, b);
    // return cb
    // cb(null, 'err');
    cb('err');
}
const t = new Tapable()
t._plugins.emit = [wait('a', 1000),
wait('b', 500),]
t._plugins.call = [call('a'),
call('b'),]

// t.applyPlugins("emit", 1, 2, (a, b) => console.log('end', a, b))
// t.applyPluginsWaterfall("call", 1, 2, (a, b) => console.log('end', a, b))
// t.applyPluginsBailResult("call", 1, 2, (a, b) => console.log('end', a, b))
// t.applyPluginsAsync("emit", 1, 2, (a, b) => console.log('end', a, b))
t.applyPluginsParallel("call", 1, 2, (a, b) => console.log('end', a, b))
// t.applyPluginsAsyncSeriesBailResult("call", 1, 2, (a, b) => console.log('end', a, b))

本项目引用的自定义外部资源