preface
The Tapable package is at the heart of the Webpack plug-in mechanism, exposing many hooks for plug-ins to use.
In V2.2.0, a total of 10 hooks are provided.
exports.SyncHook = require("./SyncHook");
exports.SyncBailHook = require("./SyncBailHook");
exports.SyncWaterfallHook = require("./SyncWaterfallHook");
exports.SyncLoopHook = require("./SyncLoopHook");
exports.AsyncParallelHook = require("./AsyncParallelHook");
exports.AsyncParallelBailHook = require("./AsyncParallelBailHook");
exports.AsyncSeriesHook = require("./AsyncSeriesHook");
exports.AsyncSeriesBailHook = require("./AsyncSeriesBailHook");
exports.AsyncSeriesLoopHook = require("./AsyncSeriesLoopHook");
exports.AsyncSeriesWaterfallHook = require("./AsyncSeriesWaterfallHook");
Copy the code
There are also two utility classes
- One is a help class with Hooks maps
exports.HookMap = require("./HookMap");
Copy the code
- One is a help class that can create a Hook and redirect to multiple other hooks
exports.MultiHook = require("./MultiHook");
Copy the code
The above source code is in tapable/lib/index.js
Hook type
Each Hook can subscribe to one or more functions, depending on their respective types.
According to the execution process, it can be divided into the following four types:
type | explain |
---|---|
Basic | It simply calls every function it subscribes to, regardless of the result of the function’s execution |
Waterfall | When a subscription function is executed, the result of the current function is passed to the next subscribed function |
Bail | When executing a subscription function, if the result returned by the current subscription function is notundefined, the subsequent subscribed functions do not continue to execute |
Loop | When a subscription is executed, if the value returned by the current subscription function is notundefined, which loops from the first subscribed function |
According to the same asynchronous can be divided into the following three types:
type | explain |
---|---|
Sync | Subscribed functions are synchronous functions, not asynchronous functions, usetapMethods the subscription |
AsyncSeries | Asynchronous serial, subscribed functions can be synchronous functions or asynchronous functions, usedtap,tapAsync,tapPromiseMethod subscription; Execute the asynchronous function for each subscription sequentially |
AsyncParallel | Asynchronous parallelism, subscribed functions can be synchronous or asynchronous functions, usedtap,tapAsync,tapPromiseMethod subscription; Execute asynchronous functions for each subscription in parallel |
The above classification is reflected in the class name, such as AsyncSeriesWaterfallHook, which has asynchronous serial execution and passes the result of execution to the next subscription function.
The sample application
Below, we will demonstrate the use method of each Hook in combination with specific examples.
SyncHook
Sample code:
const {
SyncHook
} = require('tapable');
/ / instantiate
const hook = new SyncHook(['name'.'age']);
/ / subscribe
hook.tap('js'.(name, age) = > {
console.log('js', name, age);
});
/ / subscribe
hook.tap({ name: 'css' }, (name, age) = > {
console.log('css', name, age);
});
/ / subscribe
hook.tap('node'.(name, age) = > {
console.log('node', name, age);
});
// Execute the subscription function
hook.call('naonao'.2);
Copy the code
The execution result
js naonao 2
css naonao 2
node naonao 2
Copy the code
Pay attention to
- The constructor takes an optional argument of type an array of strings
- The name of the argument received by the constructor can be defined arbitrarily. It is just a parameter, but the array length must be the same as the actual parameter received
- The number of arguments passed by the call function must be equal to the length of the array received at instantiation, and must correspond one to one
- Call execution is performed according to the order of tap subscriptions first in first out
Modified sample
Modify the above example:
The sample code
const {
SyncHook
} = require('tapable');
['aa', 'bb'] only cares about length, not the name of the member
const hook = new SyncHook(['aa'.'bb']);
// Subscribe to name, age has a value, because only two arguments are passed in call, so sex is undefined
hook.tap('js'.(name, age, sex) = > {
console.log('js', name, age, sex);
});
/ / subscribe
hook.tap({ name: 'css' }, (name, age) = > {
console.log('css', name, age);
});
// Subscription cc and dd are also line arguments, with values that correspond to the arguments passed by call
hook.tap('node'.(cc, dd) = > {
console.log('node', cc, dd);
});
// The number of subscription parameters executed must be the same as the length of the instantiation
hook.call('naonao'.2);
Copy the code
The execution result
js naonao 2 undefined
css naonao 2
node naonao 2
Copy the code
Print the hooks. The call
Why is it that way? Let’s print out the hook.call.
function anonymous(aa, bb) {
"use strict";
var _context;
var _x = this._x;
var _fn0 = _x[0];
_fn0(aa, bb);
var _fn1 = _x[1];
_fn1(aa, bb);
var _fn2 = _x[2];
_fn2(aa, bb);
}
Copy the code
So that makes sense.
The instantiated array members are parameters to the Anonymous function.
Functions subscribed to by tap are split into _fn0, _fn1, _fn2, and then executed sequentially.
When the subscription function executes, only two arguments are received, so sex in the first subscription function is undefined.
It all worked out.
SyncBailHook
Sample code:
const {
SyncBailHook
} = require('tapable');
const hook = new SyncBailHook(['name'.'age']);
hook.tap('js'.(name, age) = > {
console.log('js', name, age);
});
hook.tap({ name: 'css' }, (name, age) = > {
console.log('css', name, age);
// Return 0 instead of undefined, end at this point, subsequent subscribed functions will not be executed
return 0;
});
hook.tap('node'.(name, age) = > {
console.log('node', name, age);
});
hook.call('naonao'.2);
Copy the code
Execution Result:
js naonao 2
css naonao 2
Copy the code
Pay attention to
- If the return value of the subscription function is not undefined, subsequent subscription functions will not be executed
Print the hooks. The call
Print the hook. Call method at this point:
function anonymous(name, age) {
"use strict";
var _context;
var _x = this._x;
var _fn0 = _x[0];
var _result0 = _fn0(name, age);
if(_result0 ! = =undefined) {
return _result0;
;
} else {
var _fn1 = _x[1];
var _result1 = _fn1(name, age);
if(_result1 ! = =undefined) {
return _result1;
;
} else {
var _fn2 = _x[2];
var _result2 = _fn2(name, age);
if(_result2 ! = =undefined) {
return _result2;
;
} else{}}}}Copy the code
It calls the subscription function internally and gets the execution result of the subscription function. == operator, so it must be undefined to continue the subsequent subscription function.
SyncWaterfallHook
The sample code
const {
SyncWaterfallHook
} = require('tapable');
const hook = new SyncWaterfallHook(['name'.'age']);
hook.tap('js'.(name, age) = > {
console.log('js', name, age);
});
hook.tap({ name: 'css' }, (name, age) = > {
console.log('css', name, age);
// The return value is not undefined and will be the first argument to the next subscription function
return ` name is${name}`;
});
hook.tap('node'.(name, age) = > {
console.log('node', name, age);
});
hook.call('naonao'.2);
Copy the code
Print the result
js naonao 2
css naonao 2The node name is naonao2
Copy the code
Pay attention to
- If the result returned by the subscription function is not undefined, it will be the first argument to the next subscription function
Print the hooks. The call
Print the hook. Call method at this point:
function anonymous(name, age) {
"use strict";
var _context;
var _x = this._x;
var _fn0 = _x[0];
var _result0 = _fn0(name, age);
if(_result0 ! = =undefined) {
name = _result0;
}
var _fn1 = _x[1];
var _result1 = _fn1(name, age);
if(_result1 ! = =undefined) {
name = _result1;
}
var _fn2 = _x[2];
var _result2 = _fn2(name, age);
if(_result2 ! = =undefined) {
name = _result2;
}
return name;
}
Copy the code
It internally determines that if the result of the subscription function is not undefined it will assign the result to name which is the first parameter, and then proceed with the subsequent subscription function.
SyncLoopHook
The sample code
const {
SyncLoopHook
} = require('tapable');
const hook = new SyncLoopHook(['name'.'age']);
let count1 = 0;
let count2 = 0;
hook.tap('js'.(name, age) = > {
console.log('js', name, age);
});
hook.tap({ name: 'css' }, (name, age) = > {
console.log('css', name, age, count1);
if (++count1 === 2) {
count1 = 0;
// If the return value is undefined, the subscription function will be executed
return;
}
// The return value of the subscription function, not undefined, is reexecuted from the first subscription function
return ` name is${name}`;
});
hook.tap('node'.(name, age) = > {
console.log('node', name, age, count2);
if (++count2 === 2) {
count2 = 0;
return;
}
return 0;
});
hook.call('naonao'.2);
Copy the code
Print the result
js naonao 2
css naonao 2 0
js naonao 2
css naonao 2 1
node naonao 2 0
js naonao 2
css naonao 2 0
js naonao 2
css naonao 2 1
node naonao 2 1
Copy the code
Pay attention to
- If the return value of the subscription function is not undefined, the execution is restarted from the first subscription function.
Print the hooks. The call
Print the hook. Call method at this point:
function anonymous(name, age) {
"use strict";
var _context;
var _x = this._x;
var _loop;
do {
_loop = false;
var _fn0 = _x[0];
var _result0 = _fn0(name, age);
if(_result0 ! = =undefined) {
_loop = true;
} else {
var _fn1 = _x[1];
var _result1 = _fn1(name, age);
if(_result1 ! = =undefined) {
_loop = true;
} else {
var _fn2 = _x[2];
var _result2 = _fn2(name, age);
if(_result2 ! = =undefined) {
_loop = true;
} else {
if(! _loop) { } } } } }while (_loop);
}
Copy the code
Inside it is a do… While loop, each time the subscription function is executed, set _loop = true if the return value is not undefined and the loop is executed again, so it starts from the first subscription function.
AsyncParallelHook
You can subscribe using the TAP, tapAsync, and tapPromise methods
Tap the subscription
The sample code
const {
AsyncParallelHook
} = require('tapable');
const hook = new AsyncParallelHook(['name'.'age']);
hook.tap('js'.(name, age) = > {
// Execute asynchronously
setTimeout(() = > {
console.log('js', name, age);
}, 1000);
});
hook.tap({ name: 'css' }, (name, age) = > {
// Execute asynchronously
setTimeout(() = > {
console.log('css', name, age);
}, 2000);
});
hook.tap('node'.(name, age) = > {
// Synchronize execution
console.log('node', name, age);
});
hook.callAsync('naonao'.2.() = > {
console.log('end');
});
Copy the code
Print the result
node naonao 2
end
js naonao 2
css naonao 2
Copy the code
In the printed result, js Naonao 2 is printed one second later and CSS Naonao 2 is printed two seconds later.
Pay attention to
- The call is made using the hook. CallAsync method.
Print the hooks. CallAsync
Print the hook. CallAsync method at this point:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
do {
var _counter = 3;
var _done = (function () {
_callback();
});
if (_counter <= 0) break;
var _fn0 = _x[0];
var _hasError0 = false;
try {
_fn0(name, age);
} catch (_err) {
_hasError0 = true;
if (_counter > 0) {
_callback(_err);
_counter = 0; }}if(! _hasError0) {if (--_counter === 0) _done();
}
if (_counter <= 0) break;
var _fn1 = _x[1];
var _hasError1 = false;
try {
_fn1(name, age);
} catch (_err) {
_hasError1 = true;
if (_counter > 0) {
_callback(_err);
_counter = 0; }}if(! _hasError1) {if (--_counter === 0) _done();
}
if (_counter <= 0) break;
var _fn2 = _x[2];
var _hasError2 = false;
try {
_fn2(name, age);
} catch (_err) {
_hasError2 = true;
if (_counter > 0) {
_callback(_err);
_counter = 0; }}if(! _hasError2) {if (--_counter === 0) _done(); }}while (false);
}
Copy the code
Take a closer look inside. First, use a counter to count the number of subscription functions, execute each one sequentially, catch the subscription functions, and pass the caught errors to the callback function. Decrement the counter by one for each subscription function executed, and execute the callback only when all subscription functions have been executed.
TapAsync subscription
The sample code
const {
AsyncParallelHook
} = require('tapable');
const hook = new AsyncParallelHook(['name'.'age']);
hook.tapAsync('js'.(name, age, callback) = > {
/ / synchronize
console.log('js', name, age);
callback('js error');
});
hook.tapAsync({ name: 'css' }, (name, age) = > {
/ / asynchronous
setTimeout(() = > {
console.log('css', name, age);
}, 2000);
});
hook.callAsync('naonao'.2.err= > {
console.log('end', err);
});
Copy the code
Print the result
js naonao 2
end js error
Copy the code
Only js naonao 2 is output, the second subscribed asynchronous function is not executed, and the callback argument JS error’ is passed to the callback function.
Print the hooks. CallAsync
Print the hook. CallAsync method:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
do {
var _counter = 2;
var _done = (function () {
_callback();
});
if (_counter <= 0) break;
var _fn0 = _x[0];
_fn0(name, age, (function (_err0) {
if (_err0) {
if (_counter > 0) {
_callback(_err0);
_counter = 0; }}else {
if (--_counter === 0) _done(); }}));if (_counter <= 0) break;
var _fn1 = _x[1];
_fn1(name, age, (function (_err1) {
if (_err1) {
if (_counter > 0) {
_callback(_err1);
_counter = 0; }}else {
if (--_counter === 0) _done(); }})); }while (false);
}
Copy the code
The subscription function is executed sequentially, but when it is executed, a callback argument is added to each subscription function, so we have a callback in the subscription function. If we pass an argument when we execute callback, the internal counter is immediately set to 0 and the subsequent subscription function is stopped.
TapPromise subscription
The sample code
const {
AsyncParallelHook
} = require('tapable');
const hook = new AsyncParallelHook(['name'.'age']);
hook.tapPromise('js'.(name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('js', name, age);
resolve(1);
}, 1000);
});
});
hook.tapPromise({ name: 'css' }, (name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('css', name, age);
resolve(2);
}, 1000);
});
});
hook.promise('naonao'.2).then(result= > {
console.log('end', result);
});
Copy the code
Print the result
js naonao 2
css naonao 2
end undefined
Copy the code
Print out that the subscription function call to resovle does not pass the value because result is undefined.
Pay attention to
- With a tapPromise subscription, a Promise must be returned
Print the hooks. Promise
Print the hook. Promise method at this point:
function anonymous(name, age) {
"use strict";
var _context;
var _x = this._x;
return new Promise((function (_resolve, _reject) {
var _sync = true;
function _error(_err) {
if (_sync)
_resolve(Promise.resolve().then((function () { throw _err; })));
else
_reject(_err);
};
do {
var _counter = 2;
var _done = (function () {
_resolve();
});
if (_counter <= 0) break;
var _fn0 = _x[0];
var _hasResult0 = false;
var _promise0 = _fn0(name, age);
if(! _promise0 || ! _promise0.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise0 + ') ');
_promise0.then((function (_result0) {
_hasResult0 = true;
if (--_counter === 0) _done();
}), function (_err0) {
if (_hasResult0) throw _err0;
if (_counter > 0) {
_error(_err0);
_counter = 0; }});if (_counter <= 0) break;
var _fn1 = _x[1];
var _hasResult1 = false;
var _promise1 = _fn1(name, age);
if(! _promise1 || ! _promise1.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise1 + ') ');
_promise1.then((function (_result1) {
_hasResult1 = true;
if (--_counter === 0) _done();
}), function (_err1) {
if (_hasResult1) throw _err1;
if (_counter > 0) {
_error(_err1);
_counter = 0; }}); }while (false);
_sync = false;
}));
}
Copy the code
If you look at it, it returns a Promise internally.
After calling the subscription function, it determines whether the result returned is a Promise or throws an error.
The subscription function executes the result of resolve and is not used, so result is undefined in the final result.
AsyncParallelBailHook
This is an asynchronous parallel Hook that breaks when the subscription function returns a value other than undefined.
You can subscribe using the TAP, tapAsync, and tapPromise methods
Tap the subscription
The sample code
const {
AsyncParallelBailHook
} = require('tapable');
const hook = new AsyncParallelBailHook(['name'.'age']);
hook.tap('js'.(name, age) = > {
// Execute asynchronously
setTimeout(() = > {
console.log('js', name, age);
}, 1000);
});
hook.tap({ name: 'css' }, (name, age) = > {
// Execute asynchronously
setTimeout(() = > {
console.log('css', name, age);
}, 2000);
return 'wrong';
});
hook.tap('node'.(name, age) = > {
// Synchronize execution
console.log('node', name, age);
});
hook.callAsync('naonao'.2.err= > {
console.log('end', err);
});
Copy the code
Print the result
end null
js naonao 2
css naonao 2
Copy the code
From the execution result, the last subscription function node is not printed.
So if one of the intermediate subscription functions returns a value other than undefined, the subsequent subscription functions will not continue.
Print the hooks. CallAsync
Print the hook. CallAsync method at this point:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
var _results = new Array(3);
var _checkDone = function () {
for (var i = 0; i < _results.length; i++) {
var item = _results[i];
if (item === undefined) return false;
if(item.result ! = =undefined) {
_callback(null, item.result);
return true;
}
if (item.error) {
_callback(item.error);
return true; }}return false;
}
do {
var _counter = 3;
var _done = (function () {
_callback();
});
if (_counter <= 0) break;
var _fn0 = _x[0];
var _hasError0 = false;
try {
var _result0 = _fn0(name, age);
} catch (_err) {
_hasError0 = true;
if (_counter > 0) {
if (0 < _results.length && ((_results.length = 1), (_results[0] = { error: _err }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}if(! _hasError0) {if (_counter > 0) {
if (0< _results.length && (_result0 ! = =undefined && (_results.length = 1), (_results[0] = { result: _result0 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}if (_counter <= 0) break;
if (1 >= _results.length) {
if (--_counter === 0) _done();
} else {
var _fn1 = _x[1];
var _hasError1 = false;
try {
var _result1 = _fn1(name, age);
} catch (_err) {
_hasError1 = true;
if (_counter > 0) {
if (1 < _results.length && ((_results.length = 2), (_results[1] = { error: _err }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}if(! _hasError1) {if (_counter > 0) {
if (1< _results.length && (_result1 ! = =undefined && (_results.length = 2), (_results[1] = { result: _result1 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}}if (_counter <= 0) break;
if (2 >= _results.length) {
if (--_counter === 0) _done();
} else {
var _fn2 = _x[2];
var _hasError2 = false;
try {
var _result2 = _fn2(name, age);
} catch (_err) {
_hasError2 = true;
if (_counter > 0) {
if (2 < _results.length && ((_results.length = 3), (_results[2] = { error: _err }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}if(! _hasError2) {if (_counter > 0) {
if (2< _results.length && (_result2 ! = =undefined && (_results.length = 3), (_results[2] = { result: _result2 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done();
}
}
}
}
} while (false);
}
Copy the code
Focus on the _checkDone method, which is traversing if item.result! == undefined will call _callback directly.
Look down again do… While loop, each subscription function executes without an error, assigning its result to the array member corresponding to _result, and then calling the _checkDone method.
if (0< _results.length && (_result0 ! = =undefined && (_results.length = 1), (_results[0] = { result: _result0 }), _checkDone())) {
_counter = 0;
}
Copy the code
TapAsync subscription
The sample code
const {
AsyncParallelBailHook
} = require('tapable');
const hook = new AsyncParallelBailHook(['name'.'age']);
hook.tapAsync('js'.(name, age, callback) = > {
// Execute asynchronously
setTimeout(() = > {
console.log('js', name, age);
}, 1000);
callback();
});
hook.tapAsync({ name: 'css' }, (name, age, callback) = > {
// Execute asynchronously
setTimeout(() = > {
console.log('css', name, age);
}, 2000);
callback('css error');
});
hook.tapAsync('node'.(name, age, callback) = > {
// Synchronize execution
console.log('node', name, age);
callback();
});
hook.callAsync('naonao'.2.err= > {
console.log('end', err);
});
Copy the code
Print the result
end css error
js naonao 2
css naonao 2
Copy the code
The last subscription function, Node, is not printed.
Pay attention to
- If the subscription function callback has arguments, subsequent subscription function executions are terminated
- Each subscription function takes an additional callback argument and must be executed
Print the hooks. CallAsync
Print the hook. CallAsync method at this point:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
var _results = new Array(3);
var _checkDone = function () {
for (var i = 0; i < _results.length; i++) {
var item = _results[i];
if (item === undefined) return false;
if(item.result ! = =undefined) {
_callback(null, item.result);
return true;
}
if (item.error) {
_callback(item.error);
return true; }}return false;
}
do {
var _counter = 3;
var _done = (function () {
_callback();
});
if (_counter <= 0) break;
var _fn0 = _x[0];
_fn0(name, age, (function (_err0, _result0) {
if (_err0) {
if (_counter > 0) {
if (0 < _results.length && ((_results.length = 1), (_results[0] = { error: _err0 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}else {
if (_counter > 0) {
if (0< _results.length && (_result0 ! = =undefined && (_results.length = 1), (_results[0] = { result: _result0 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}}));if (_counter <= 0) break;
if (1 >= _results.length) {
if (--_counter === 0) _done();
} else {
var _fn1 = _x[1];
_fn1(name, age, (function (_err1, _result1) {
if (_err1) {
if (_counter > 0) {
if (1 < _results.length && ((_results.length = 2), (_results[1] = { error: _err1 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}else {
if (_counter > 0) {
if (1< _results.length && (_result1 ! = =undefined && (_results.length = 2), (_results[1] = { result: _result1 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}})); }if (_counter <= 0) break;
if (2 >= _results.length) {
if (--_counter === 0) _done();
} else {
var _fn2 = _x[2];
_fn2(name, age, (function (_err2, _result2) {
if (_err2) {
if (_counter > 0) {
if (2 < _results.length && ((_results.length = 3), (_results[2] = { error: _err2 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}else {
if (_counter > 0) {
if (2< _results.length && (_result2 ! = =undefined && (_results.length = 3), (_results[2] = { result: _result2 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}})); }}while (false);
}
Copy the code
Because each subscription function adds a callback argument, and the result is the processing done in that callback, So each subscription function must execute a callback, otherwise the _checkDone and callAsync callback may not be executed.
TapPromise subscription
The sample code
const {
AsyncParallelBailHook
} = require('tapable');
const hook = new AsyncParallelBailHook(['name'.'age']);
hook.tapPromise('js'.(name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('js', name, age);
resolve(1);
}, 2000);
});
});
hook.tapPromise({ name: 'css' }, (name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('css', name, age);
resolve(2);
}, 1000);
});
});
hook.tapPromise('node'.(name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('node', name, age);
resolve(3);
}, 3000);
});
});
hook.promise('naonao'.2).then(result= > {
console.log('end', result);
}, err= > {
console.log('end', erro);
});
Copy the code
Print the result
css naonao 2
js naonao 2
end 1
node naonao 2
Copy the code
The 1 printed at the end, not the 3. And continue printing node nanonao 2 after end.
Pay attention to
- The then method of hook. Promise is called as soon as there is a subscription function resolve or Reject
- The resolve value of the hook.promise’s then takes the first resolve value in order of the subscription functions.
Print the hooks. Promise
Print the hook. Promise method at this point:
function anonymous(name, age) {
"use strict";
var _context;
var _x = this._x;
return new Promise((function (_resolve, _reject) {
var _sync = true;
function _error(_err) {
if (_sync)
_resolve(Promise.resolve().then((function () { throw _err; })));
else
_reject(_err);
};
var _results = new Array(3);
var _checkDone = function () {
for (var i = 0; i < _results.length; i++) {
var item = _results[i];
if (item === undefined) return false;
if(item.result ! = =undefined) {
_resolve(item.result);
return true;
}
if (item.error) {
_error(item.error);
return true; }}return false;
}
do {
var _counter = 3;
var _done = (function () {
_resolve();
});
if (_counter <= 0) break;
var _fn0 = _x[0];
var _hasResult0 = false;
var _promise0 = _fn0(name, age);
if(! _promise0 || ! _promise0.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise0 + ') ');
_promise0.then((function (_result0) {
_hasResult0 = true;
if (_counter > 0) {
if (0< _results.length && (_result0 ! = =undefined && (_results.length = 1), (_results[0] = { result: _result0 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}),function (_err0) {
if (_hasResult0) throw _err0;
if (_counter > 0) {
if (0 < _results.length && ((_results.length = 1), (_results[0] = { error: _err0 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}});if (_counter <= 0) break;
if (1 >= _results.length) {
if (--_counter === 0) _done();
} else {
var _fn1 = _x[1];
var _hasResult1 = false;
var _promise1 = _fn1(name, age);
if(! _promise1 || ! _promise1.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise1 + ') ');
_promise1.then((function (_result1) {
_hasResult1 = true;
if (_counter > 0) {
if (1< _results.length && (_result1 ! = =undefined && (_results.length = 2), (_results[1] = { result: _result1 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}),function (_err1) {
if (_hasResult1) throw _err1;
if (_counter > 0) {
if (1 < _results.length && ((_results.length = 2), (_results[1] = { error: _err1 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}); }if (_counter <= 0) break;
if (2 >= _results.length) {
if (--_counter === 0) _done();
} else {
var _fn2 = _x[2];
var _hasResult2 = false;
var _promise2 = _fn2(name, age);
if(! _promise2 || ! _promise2.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise2 + ') ');
_promise2.then((function (_result2) {
_hasResult2 = true;
if (_counter > 0) {
if (2< _results.length && (_result2 ! = =undefined && (_results.length = 3), (_results[2] = { result: _result2 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}),function (_err2) {
if (_hasResult2) throw _err2;
if (_counter > 0) {
if (2 < _results.length && ((_results.length = 3), (_results[2] = { error: _err2 }), _checkDone())) {
_counter = 0;
} else {
if (--_counter === 0) _done(); }}}); }}while (false);
_sync = false;
}));
}
Copy the code
Focus on the _checkDone method, which leaves the _resolve call if the subscription function’s resolve is not undefined.
Look at the do… While, the resolve of each subscription function is stored in the _result value of the corresponding index, and the _checkDone method is executed if the value is not undefined.
AsyncSeriesHook
Asynchronous serial Hook.
You can subscribe using the TAP, tapAsync, and tapPromise methods
Tap the subscription
The sample code
const {
AsyncSeriesHook
} = require('tapable');
const hook = new AsyncSeriesHook(['name'.'age']);
hook.tap('js'.(name, age) = > {
setTimeout(() = > {
console.log('js', name, age);
}, 2000);
});
hook.tap({ name: 'css' }, (name, age) = > {
setTimeout(() = > {
console.log('css', name, age);
}, 1000);
});
hook.tap('node'.(name, age) = > {
setTimeout(() = > {
console.log('node', name, age);
}, 3000);
});
hook.callAsync('naonao'.2.result= > {
console.log('end', result);
});
Copy the code
Print result:
end undefined
css naonao 2
js naonao 2
node naonao 2
Copy the code
From the printed results, the subscription functions are executed sequentially.
Pay attention to
- Subscription functions are executed sequentially, with subsequent subscription functions interrupted if errors are encountered
Print the hooks. CallAsync
Print the hook. CallAsync method at this point:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
var _fn0 = _x[0];
var _hasError0 = false;
try {
_fn0(name, age);
} catch (_err) {
_hasError0 = true;
_callback(_err);
}
if(! _hasError0) {var _fn1 = _x[1];
var _hasError1 = false;
try {
_fn1(name, age);
} catch (_err) {
_hasError1 = true;
_callback(_err);
}
if(! _hasError1) {var _fn2 = _x[2];
var _hasError2 = false;
try {
_fn2(name, age);
} catch (_err) {
_hasError2 = true;
_callback(_err);
}
if(! _hasError2) { _callback(); }}}}Copy the code
As you can see, it is executed in the order of the subscription functions, and the callback function is called immediately if an error is encountered during execution.
TapAsync subscription
The sample code
const {
AsyncSeriesHook
} = require('tapable');
const hook = new AsyncSeriesHook(['name'.'age']);
hook.tapAsync('js'.(name, age, callback) = > {
setTimeout(() = > {
console.log('js', name, age);
}, 2000);
callback();
});
hook.tapAsync({ name: 'css' }, (name, age, callback) = > {
setTimeout(() = > {
console.log('css', name, age);
}, 1000);
callback('css error');
});
hook.tapAsync('node'.(name, age, callback) = > {
setTimeout(() = > {
console.log('node', name, age);
}, 3000);
callback();
});
hook.callAsync('naonao'.2.result= > {
console.log('end', result);
});
Copy the code
Print the result
end css error
css naonao 2
js naonao 2
Copy the code
The third subscription function node is not printed. But JS is later than CSS printing.
Pay attention to
- If the subscription function’s callback passes a non-undefined value, subsequent subscription functions will not be executed
- Subscription functions are executed sequentially, but still as event loops if there is asynchronous code
Print the hooks. CallAsync
Print the hook. CallAsync method at this point:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
function _next1() {
var _fn2 = _x[2];
_fn2(name, age, (function (_err2) {
if (_err2) {
_callback(_err2);
} else{ _callback(); }})); }function _next0() {
var _fn1 = _x[1];
_fn1(name, age, (function (_err1) {
if (_err1) {
_callback(_err1);
} else{ _next1(); }})); }var _fn0 = _x[0];
_fn0(name, age, (function (_err0) {
if (_err0) {
_callback(_err0);
} else{ _next0(); }})); }Copy the code
Notice that each subscription function is executed with a callback argument that calls the next subscription function. If the subscription function executes incorrectly, it leaves the final callback and does not execute the next subscription function, resulting in sequential execution.
TapPromise subscription
The sample code
const {
AsyncSeriesHook
} = require('tapable');
const hook = new AsyncSeriesHook(['name'.'age']);
hook.tapPromise('js'.(name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('js', name, age);
resolve();
}, 2000);
});
});
hook.tapPromise({ name: 'css' }, (name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('css', name, age);
resolve(2);
}, 1000);
});
});
hook.tapPromise('node'.(name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('node', name, age);
resolve(3);
}, 3000);
});
});
hook.promise('naonao'.2).then(result= > {
console.log('end', result);
}, err= > {
console.log('end', erro);
});
Copy the code
Print the result
js naonao 2
css naonao 2
node naonao 2
end undefined
Copy the code
From the print, it is executed sequentially, and the resolve value of the subscription function is not passed to the final callback function.
Pay attention to
- Execution is in the order of subscription
Print the hooks. Promise
Print the hook. Promise method at this point:
function anonymous(name, age) {
"use strict";
var _context;
var _x = this._x;
return new Promise((function (_resolve, _reject) {
var _sync = true;
function _error(_err) {
if (_sync)
_resolve(Promise.resolve().then((function () { throw _err; })));
else
_reject(_err);
};
function _next1() {
var _fn2 = _x[2];
var _hasResult2 = false;
var _promise2 = _fn2(name, age);
if(! _promise2 || ! _promise2.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise2 + ') ');
_promise2.then((function (_result2) {
_hasResult2 = true;
_resolve();
}), function (_err2) {
if (_hasResult2) throw _err2;
_error(_err2);
});
}
function _next0() {
var _fn1 = _x[1];
var _hasResult1 = false;
var _promise1 = _fn1(name, age);
if(! _promise1 || ! _promise1.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise1 + ') ');
_promise1.then((function (_result1) {
_hasResult1 = true;
_next1();
}), function (_err1) {
if (_hasResult1) throw _err1;
_error(_err1);
});
}
var _fn0 = _x[0];
var _hasResult0 = false;
var _promise0 = _fn0(name, age);
if(! _promise0 || ! _promise0.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise0 + ') ');
_promise0.then((function (_result0) {
_hasResult0 = true;
_next0();
}), function (_err0) {
if (_hasResult0) throw _err0;
_error(_err0);
});
_sync = false;
}));
}
Copy the code
If you look at the then method that each subscription function executes, _promise0. Then calls _next0 internally, which calls the second subscription function _promise1, which then calls _next1 internally, to achieve a traversal effect.
AsyncSeriesBailHook
An asynchronous serial Hook, but interrupts the execution of subsequent subscription functions as long as the return value of the subscription function is not undefined.
You can subscribe using the TAP, tapAsync, and tapPromise methods
Tap the subscription
The sample code
const {
AsyncSeriesBailHook
} = require('tapable');
const hook = new AsyncSeriesBailHook(['name'.'age']);
hook.tap('js'.(name, age) = > {
setTimeout(() = > {
console.log('js', name, age);
}, 2000);
});
hook.tap({ name: 'css' }, (name, age) = > {
setTimeout(() = > {
console.log('css', name, age);
}, 1000);
return 'wrong';
});
hook.tap('node'.(name, age) = > {
setTimeout(() = > {
console.log('node', name, age);
}, 3000);
});
hook.callAsync('naonao'.2.result= > {
console.log('end', result);
});
Copy the code
Print the result
end null
css naonao 2
js naonao 2
Copy the code
The last subscription function node is not printed because the second subscription function returns a non-undefined value.
Print the hooks. CallAsync
Print the hook. CallAsync method at this point:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
var _fn0 = _x[0];
var _hasError0 = false;
try {
var _result0 = _fn0(name, age);
} catch (_err) {
_hasError0 = true;
_callback(_err);
}
if(! _hasError0) {if(_result0 ! = =undefined) {
_callback(null, _result0);
} else {
var _fn1 = _x[1];
var _hasError1 = false;
try {
var _result1 = _fn1(name, age);
} catch (_err) {
_hasError1 = true;
_callback(_err);
}
if(! _hasError1) {if(_result1 ! = =undefined) {
_callback(null, _result1);
} else {
var _fn2 = _x[2];
var _hasError2 = false;
try {
var _result2 = _fn2(name, age);
} catch (_err) {
_hasError2 = true;
_callback(_err);
}
if(! _hasError2) {if(_result2 ! = =undefined) {
_callback(null, _result2);
} else {
_callback();
}
}
}
}
}
}
}
Copy the code
As you can see from the code, it is executed sequentially, and if the subscription function returns a value other than undefined or has an error, the final callback is executed immediately.
TapAsync subscription
The sample code
const {
AsyncSeriesBailHook
} = require('tapable');
const hook = new AsyncSeriesBailHook(['name'.'age']);
hook.tapAsync('js'.(name, age, callback) = > {
setTimeout(() = > {
console.log('js', name, age);
}, 2000);
callback();
});
hook.tapAsync({ name: 'css' }, (name, age, callback) = > {
setTimeout(() = > {
console.log('css', name, age);
}, 1000);
callback('css error');
});
hook.tapAsync('node'.(name, age, callback) = > {
setTimeout(() = > {
console.log('node', name, age);
}, 3000);
callback();
});
hook.callAsync('naonao'.2.result= > {
console.log('end', result);
});
Copy the code
Print the result
end css error
css naonao 2
js naonao 2
Copy the code
The last subscription function, Node, is not printed.
The reason CSS is printed first and JS is because of an internal setTimeout.
Print the hooks. CallAsync
Print the hook. CallAsync method at this point:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
function _next1() {
var _fn2 = _x[2];
_fn2(name, age, (function (_err2, _result2) {
if (_err2) {
_callback(_err2);
} else {
if(_result2 ! = =undefined) {
_callback(null, _result2);
} else{ _callback(); }}})); }function _next0() {
var _fn1 = _x[1];
_fn1(name, age, (function (_err1, _result1) {
if (_err1) {
_callback(_err1);
} else {
if(_result1 ! = =undefined) {
_callback(null, _result1);
} else{ _next1(); }}})); }var _fn0 = _x[0];
_fn0(name, age, (function (_err0, _result0) {
if (_err0) {
_callback(_err0);
} else {
if(_result0 ! = =undefined) {
_callback(null, _result0);
} else{ _next0(); }}})); }Copy the code
As you can see from the code, each subscription function adds a callback argument, which is executed internally. If there is an error or the return value is not undefined, the final callback will be executed immediately, otherwise the next subscription function will be executed.
This achieves the effect of sequential execution.
TapPromise subscription
The sample code
const {
AsyncSeriesBailHook
} = require('tapable');
const hook = new AsyncSeriesBailHook(['name'.'age']);
hook.tapPromise('js'.(name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('js', name, age);
resolve();
}, 2000);
});
});
hook.tapPromise({ name: 'css' }, (name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('css', name, age);
resolve(2);
}, 1000);
});
});
hook.tapPromise('node'.(name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('node', name, age);
resolve(3);
}, 3000);
});
});
hook.promise('naonao'.2).then(result= > {
console.log('end', result);
}, err= > {
console.log('end', err);
});
Copy the code
Print the result
js naonao 2
css naonao 2
end 2
Copy the code
The last subscription function, Node, is not printed.
The execution is sequential, and when the subscription function resolve passes a value other than undefined, the final promise.then is executed, and subsequent subscription functions are not executed.
Print the hooks. Promise
Print the hook. Promise method at this point:
function anonymous(name, age) {
"use strict";
var _context;
var _x = this._x;
return new Promise((function (_resolve, _reject) {
var _sync = true;
function _error(_err) {
if (_sync)
_resolve(Promise.resolve().then((function () { throw _err; })));
else
_reject(_err);
};
function _next1() {
var _fn2 = _x[2];
var _hasResult2 = false;
var _promise2 = _fn2(name, age);
if(! _promise2 || ! _promise2.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise2 + ') ');
_promise2.then((function (_result2) {
_hasResult2 = true;
if(_result2 ! = =undefined) {
_resolve(_result2);
} else{ _resolve(); }}),function (_err2) {
if (_hasResult2) throw _err2;
_error(_err2);
});
}
function _next0() {
var _fn1 = _x[1];
var _hasResult1 = false;
var _promise1 = _fn1(name, age);
if(! _promise1 || ! _promise1.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise1 + ') ');
_promise1.then((function (_result1) {
_hasResult1 = true;
if(_result1 ! = =undefined) {
_resolve(_result1);
} else{ _next1(); }}),function (_err1) {
if (_hasResult1) throw _err1;
_error(_err1);
});
}
var _fn0 = _x[0];
var _hasResult0 = false;
var _promise0 = _fn0(name, age);
if(! _promise0 || ! _promise0.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise0 + ') ');
_promise0.then((function (_result0) {
_hasResult0 = true;
if(_result0 ! = =undefined) {
_resolve(_result0);
} else{ _next0(); }}),function (_err0) {
if (_hasResult0) throw _err0;
_error(_err0);
});
_sync = false;
}));
}
Copy the code
As you can see from the code, the subscription function’s then method, if the value of resolve is not undefined, calls the final _resolve method and passes the value, otherwise calls the next subscription function.
AsyncSeriesLoopHook
Asynchronous serial loop hooks can be subscribed using the TAP, tapAsync, and tapPromise methods
Tap the subscription
The sample code
const {
AsyncSeriesLoopHook
} = require('tapable');
const hook = new AsyncSeriesLoopHook(['name'.'age']);
let count1 = 0;
let count2 = 0;
hook.tap('js'.(name, age) = > {
if (++count1 >= 2) {
console.log('js', name, age, count1);
return;
} else {
console.log('js', name, age, count1);
return 'js1'; }}); hook.tap('node'.(name, age) = > {
if (++count2 >= 2) {
console.log('node', name, age, count2);
return;
} else {
console.log('node', name, age, count2);
return 'node2'; }}); hook.callAsync('naonao'.2.err= > {
console.log('end', err);
});
Copy the code
Print the result
js naonao 2 1
js naonao 2 2
node naonao 2 1
js naonao 2 3
node naonao 2 2
end undefined
Copy the code
If the subscription function returns a value other than undefined, the loop will start with the first subscription.
Print the hooks. CallAsync
Print the hook. CallAsync method at this point:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
var _loop;
do {
_loop = false;
var _fn0 = _x[0];
var _hasError0 = false;
try {
var _result0 = _fn0(name, age);
} catch (_err) {
_hasError0 = true;
_callback(_err);
}
if(! _hasError0) {if(_result0 ! = =undefined) {
_loop = true;
} else {
var _fn1 = _x[1];
var _hasError1 = false;
try {
var _result1 = _fn1(name, age);
} catch (_err) {
_hasError1 = true;
_callback(_err);
}
if(! _hasError1) {if(_result1 ! = =undefined) {
_loop = true;
} else {
if(! _loop) { _callback(); } } } } } }while (_loop);
}
Copy the code
As you can see from the code, the return value of each subscription function is set to true if it is not undefined, then do… The while will start the loop from the beginning.
TapAsync subscription
The sample code
const {
AsyncSeriesLoopHook
} = require('tapable');
const hook = new AsyncSeriesLoopHook(['name'.'age']);
let count1 = 0;
let count2 = 0;
hook.tapAsync('js'.(name, age, callback) = > {
if (++count1 >= 2) {
console.log('js', name, age, count1);
callback();
} else {
console.log('js', name, age, count1);
callback(null.'js1'); }}); hook.tapAsync('node'.(name, age, callback) = > {
if (++count2 >= 2) {
console.log('node', name, age, count2);
callback();
} else {
console.log('node', name, age, count2);
callback(null.'node2'); }}); hook.callAsync('naonao'.2.err= > {
console.log('end', err);
});
Copy the code
Print the result
js naonao 2 1
js naonao 2 2
node naonao 2 1
js naonao 2 3
node naonao 2 2
end undefined
Copy the code
If the second parameter of callback is not undefined, the loop will start from the beginning.
Print the hooks. CallAsync
Print the hook. CallAsync method at this point:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
var _looper = (function () {
var _loopAsync = false;
var _loop;
do {
_loop = false;
function _next0() {
var _fn1 = _x[1];
_fn1(name, age, (function (_err1, _result1) {
if (_err1) {
_callback(_err1);
} else {
if(_result1 ! = =undefined) {
_loop = true;
if (_loopAsync) _looper();
} else {
if(! _loop) { _callback(); }}}})); }var _fn0 = _x[0];
_fn0(name, age, (function (_err0, _result0) {
if (_err0) {
_callback(_err0);
} else {
if(_result0 ! = =undefined) {
_loop = true;
if (_loopAsync) _looper();
} else{ _next0(); }}})); }while (_loop);
_loopAsync = true;
});
_looper();
}
Copy the code
If the second argument of the subscription function is not undefined, the _looper method will be called again, thus executing the loop from the subscription function.
TapPromise subscription
The sample code
const {
AsyncSeriesLoopHook
} = require('tapable');
const hook = new AsyncSeriesLoopHook(['name'.'age']);
let count1 = 0;
let count2 = 0;
hook.tapPromise('js'.(name, age) = > {
return new Promise((resolve, reject) = > {
if (++count1 >= 2) {
console.log('js', name, age, count1);
resolve();
} else {
console.log('js', name, age, count1);
resolve('js1'); }}); }); hook.tapPromise('node'.(name, age) = > {
return new Promise((resolve, reject) = > {
if (++count2 >= 2) {
console.log('node', name, age, count1);
resolve();
} else {
console.log('node', name, age, count1);
resolve('node2'); }}); }); hook.promise('naonao'.2).then(result= > {
console.log('end', result);
}, err= > {
console.log('end', err);
});
Copy the code
Print the result
js naonao 2 1
js naonao 2 2
node naonao 2 2
js naonao 2 3
node naonao 2 3
end undefined
Copy the code
If the subscription function resolve is not undefined, the next subscription function will not be executed until undefined.
Print the hooks. Promise
Print the hook. Promise method at this point:
function anonymous(name, age) {
"use strict";
var _context;
var _x = this._x;
return new Promise((function (_resolve, _reject) {
var _sync = true;
function _error(_err) {
if (_sync)
_resolve(Promise.resolve().then((function () { throw _err; })));
else
_reject(_err);
};
var _looper = (function () {
var _loopAsync = false;
var _loop;
do {
_loop = false;
function _next0() {
var _fn1 = _x[1];
var _hasResult1 = false;
var _promise1 = _fn1(name, age);
if(! _promise1 || ! _promise1.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise1 + ') ');
_promise1.then((function (_result1) {
_hasResult1 = true;
if(_result1 ! = =undefined) {
_loop = true;
if (_loopAsync) _looper();
} else {
if(! _loop) { _resolve(); }}}),function (_err1) {
if (_hasResult1) throw _err1;
_error(_err1);
});
}
var _fn0 = _x[0];
var _hasResult0 = false;
var _promise0 = _fn0(name, age);
if(! _promise0 || ! _promise0.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise0 + ') ');
_promise0.then((function (_result0) {
_hasResult0 = true;
if(_result0 ! = =undefined) {
_loop = true;
if (_loopAsync) _looper();
} else{ _next0(); }}),function (_err0) {
if (_hasResult0) throw _err0;
_error(_err0);
});
} while (_loop);
_loopAsync = true;
});
_looper();
_sync = false;
}));
}
Copy the code
As you can see from the code, it defines a _looper function. If resolve is not undefined, the _looper function will be re-executed, starting with the first subscription function.
AsyncSeriesWaterfallHook
Asynchronous serial Hook, but passes the return value (not undefined) of the current subscription function to the next subscription function as a fixed argument.
You can subscribe using the TAP, tapAsync, and tapPromise methods
Tap the subscription
The sample code
const {
AsyncSeriesWaterfallHook
} = require('tapable');
const hook = new AsyncSeriesWaterfallHook(['name'.'age']);
hook.tap('js'.(name, age) = > {
setTimeout(() = > {
console.log('js', name, age);
}, 2000);
return 'js1';
});
hook.tap({ name: 'css' }, (name, age) = > {
setTimeout(() = > {
console.log('css', name, age);
}, 1000);
return 'css2';
});
hook.tap('node'.(name, age) = > {
setTimeout(() = > {
console.log('node', name, age);
}, 3000);
return 'node3';
});
hook.callAsync('naonao'.2.(err, result) = > {
console.log('end', err, result);
});
Copy the code
Print the result
end null node3
css js1 2
js naonao 2
node css2 2
Copy the code
As you can see from the print, the return value of the previous subscription function (not undefined) is passed to the current subscription function and used as the first argument.
Print the hooks. CallAsync
Print the hook. CallAsync method at this point:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
var _fn0 = _x[0];
var _hasError0 = false;
try {
var _result0 = _fn0(name, age);
} catch (_err) {
_hasError0 = true;
_callback(_err);
}
if(! _hasError0) {if(_result0 ! = =undefined) {
name = _result0;
}
var _fn1 = _x[1];
var _hasError1 = false;
try {
var _result1 = _fn1(name, age);
} catch (_err) {
_hasError1 = true;
_callback(_err);
}
if(! _hasError1) {if(_result1 ! = =undefined) {
name = _result1;
}
var _fn2 = _x[2];
var _hasError2 = false;
try {
var _result2 = _fn2(name, age);
} catch (_err) {
_hasError2 = true;
_callback(_err);
}
if(! _hasError2) {if(_result2 ! = =undefined) {
name = _result2;
}
_callback(null, name); }}}}Copy the code
As you can see from the code, the return value of each subscription function, if not undefined, is assigned to the first parameter, and then the next subscription function is called.
If you look at the call to the _callback method, its second argument is the first argument passed in the callAsync call.
TapAsync subscription
The sample code
const {
AsyncSeriesWaterfallHook
} = require('tapable');
const hook = new AsyncSeriesWaterfallHook(['name'.'age']);
hook.tapAsync('js'.(name, age, callback) = > {
setTimeout(() = > {
console.log('js', name, age);
}, 2000);
callback(null.'js1');
});
hook.tapAsync({ name: 'css' }, (name, age, callback) = > {
setTimeout(() = > {
console.log('css', name, age);
}, 1000);
callback(null.'css2');
});
hook.tapAsync('node'.(name, age, callback) = > {
setTimeout(() = > {
console.log('node', name, age);
}, 3000);
callback(null.'node3');
});
hook.callAsync('naonao'.2.(err, result) = > {
console.log('end', err, result);
});
Copy the code
Print the result
end null node3
css js1 2
js naonao 2
node css2 2
Copy the code
From the print result, the second argument to the callback function in the subscription function is passed.
Print the hooks. CallAsync
Print the hook. CallAsync method at this point:
function anonymous(name, age, _callback) {
"use strict";
var _context;
var _x = this._x;
function _next1() {
var _fn2 = _x[2];
_fn2(name, age, (function (_err2, _result2) {
if (_err2) {
_callback(_err2);
} else {
if(_result2 ! = =undefined) {
name = _result2;
}
_callback(null, name); }})); }function _next0() {
var _fn1 = _x[1];
_fn1(name, age, (function (_err1, _result1) {
if (_err1) {
_callback(_err1);
} else {
if(_result1 ! = =undefined) { name = _result1; } _next1(); }})); }var _fn0 = _x[0];
_fn0(name, age, (function (_err0, _result0) {
if (_err0) {
_callback(_err0);
} else {
if(_result0 ! = =undefined) { name = _result0; } _next0(); }})); }Copy the code
As you can see from the code, the third argument to the subscription function is a method that assigns the value of the method’s second argument (not undefined) to name. Then the next subscription function is called.
TapPromise subscription
The sample code
const {
AsyncSeriesWaterfallHook
} = require('tapable');
const hook = new AsyncSeriesWaterfallHook(['name'.'age']);
hook.tapPromise('js'.(name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('js', name, age);
resolve('js1');
}, 2000);
});
});
hook.tapPromise({ name: 'css' }, (name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('css', name, age);
resolve('css2');
}, 1000);
});
});
hook.tapPromise('node'.(name, age) = > {
return new Promise((resolve, reject) = > {
setTimeout(() = > {
console.log('node', name, age);
resolve('node3');
}, 3000);
});
});
hook.promise('naonao'.2).then(result= > {
console.log('end', result);
}, err= > {
console.log('end', err);
});
Copy the code
Print the result
js naonao 2
css js1 2
node css2 2
end node3
Copy the code
From the print, the resolve value of the subscription function is passed to the next subscription function.
Print the hooks. Promise
Print the hook. Promise method at this point:
function anonymous(name, age) {
"use strict";
var _context;
var _x = this._x;
return new Promise((function (_resolve, _reject) {
var _sync = true;
function _error(_err) {
if (_sync)
_resolve(Promise.resolve().then((function () { throw _err; })));
else
_reject(_err);
};
function _next1() {
var _fn2 = _x[2];
var _hasResult2 = false;
var _promise2 = _fn2(name, age);
if(! _promise2 || ! _promise2.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise2 + ') ');
_promise2.then((function (_result2) {
_hasResult2 = true;
if(_result2 ! = =undefined) {
name = _result2;
}
_resolve(name);
}), function (_err2) {
if (_hasResult2) throw _err2;
_error(_err2);
});
}
function _next0() {
var _fn1 = _x[1];
var _hasResult1 = false;
var _promise1 = _fn1(name, age);
if(! _promise1 || ! _promise1.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise1 + ') ');
_promise1.then((function (_result1) {
_hasResult1 = true;
if(_result1 ! = =undefined) {
name = _result1;
}
_next1();
}), function (_err1) {
if (_hasResult1) throw _err1;
_error(_err1);
});
}
var _fn0 = _x[0];
var _hasResult0 = false;
var _promise0 = _fn0(name, age);
if(! _promise0 || ! _promise0.then)throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise0 + ') ');
_promise0.then((function (_result0) {
_hasResult0 = true;
if(_result0 ! = =undefined) {
name = _result0;
}
_next0();
}), function (_err0) {
if (_hasResult0) throw _err0;
_error(_err0);
});
_sync = false;
}));
}
Copy the code
As you can see from the code, the subscription function’s resolve value, if not undefined, is assigned to name before the next subscription function is called.
conclusion
This is a sample application of all Tapable hooks.
Through the example, you can understand the features and usage of each Hook. Printing out the calling method of each Hook at the same time can help us better understand the real execution logic inside them.
The next article is about Interception interceptors.
More exciting, please pay attention to the wechat public number: make a noise front end