AsyncSeriesHook 异步串行
从 tapable 生产的脚本来看 AsyncSeriesHook
先来看 tapAsync+ callAsync
const {AsyncSeriesHook} = require("tapable");
let queue2 = new AsyncSeriesHook(['name']);
console.time('cost2');
queue2.tapAsync('1', function (name, cb) {setTimeout(() => {console.log(name, 1);
cb();}, 1000);
});
queue2.tapAsync('2', function (name, cb) {setTimeout(() => {console.log(name, 2);
cb();}, 2000);
});
queue2.tapAsync('3', function (name, cb) {setTimeout(() => {console.log(name, 3);
cb();}, 3000);
});
queue2.callAsync('webpack', (err) => {console.log(err);
console.log('over');
console.timeEnd('cost2');
});
// 执行结果
/*
webpack 1
webpack 2
webpack 3
undefined
over
cost2: 6019.621ms
*/
源码:
"use strict";
var _context;
var _x = this._x;
function _next1() {var _fn2 = _x[2];
_fn2(name, _err2 => {if (_err2) {_callback(_err2);
} else {_callback();
}
});
}
function _next0() {var _fn1 = _x[1];
_fn1(name, _err1 => {if (_err1) {_callback(_err1);
} else {_next1();
}
});
}
var _fn0 = _x[0];
_fn0(name, _err0 => {if (_err0) {_callback(_err0);
} else {_next0();
}
});
从以上看,特别简单,串行执行。
再看下 tap 加 callAsync
const {AsyncSeriesHook} = require("tapable");
// tap
let queue1 = new AsyncSeriesHook(['name']);
console.time('cost1');
queue1.tap('1', function (name) {console.log(1);
return "Wrong";
});
queue1.tap('2', function (name) {console.log(2);
});
queue1.tap('3', function (name) {console.log(3);
});
queue1.callAsync('zfpx', err => {console.log(err);
console.timeEnd('cost1');
});
// 执行结果
/*
1
2
3
undefined
cost1: 3.933ms
*/
源码:
"use strict";
var _context;
var _x = this._x;
var _fn0 = _x[0];
var _hasError0 = false;
try {_fn0(name);
} catch (_err) {
_hasError0 = true;
_callback(_err);
}
if (!_hasError0) {var _fn1 = _x[1];
var _hasError1 = false;
try {_fn1(name);
} catch (_err) {
_hasError1 = true;
_callback(_err);
}
if (!_hasError1) {var _fn2 = _x[2];
var _hasError2 = false;
try {_fn2(name);
} catch (_err) {
_hasError2 = true;
_callback(_err);
}
if (!_hasError2) {_callback();
}
}
}
即 顺序执行,报错就提前执行总 callback
再来看:
tapPromise + promise
const {AsyncSeriesHook} = require("tapable");
let queue3 = new AsyncSeriesHook(['name']);
console.time('cost3');
queue3.tapPromise('1',function(name){return new Promise(function(resolve){setTimeout(function(){console.log(name, 1);
resolve();},1000)
});
});
queue3.tapPromise('2',function(name,callback){return new Promise(function(resolve){setTimeout(function(){console.log(name, 2);
resolve();},2000)
});
});
queue3.tapPromise('3',function(name,callback){return new Promise(function(resolve){setTimeout(function(){console.log(name, 3);
resolve();},3000)
});
});
queue3.promise('webapck').then(err=>{console.log(err);
console.timeEnd('cost3');
});
// 执行结果
/*
webapck 1
webapck 2
webapck 3
undefined
cost3: 6021.817ms
*/
源码:
"use strict";
return new Promise((_resolve, _reject) => {
var _sync = true;
function _error(_err) {if (_sync)
_resolve(Promise.resolve().then(() => {throw _err;}));
else
_reject(_err);
};
var _context;
var _x = this._x;
function _next1() {var _fn2 = _x[2];
var _hasResult2 = false;
var _promise2 = _fn2(name);
if (!_promise2 || !_promise2.then)
throw new Error('Tap function (tapPromise) did not return promise (returned' + _promise2 + ')');
_promise2.then(_result2 => {
_hasResult2 = true;
_resolve();}, _err2 => {if (_hasResult2) throw _err2;
_error(_err2);
});
}
function _next0() {var _fn1 = _x[1];
var _hasResult1 = false;
var _promise1 = _fn1(name);
if (!_promise1 || !_promise1.then)
throw new Error('Tap function (tapPromise) did not return promise (returned' + _promise1 + ')');
_promise1.then(_result1 => {
_hasResult1 = true;
_next1();}, _err1 => {if (_hasResult1) throw _err1;
_error(_err1);
});
}
var _fn0 = _x[0];
var _hasResult0 = false;
var _promise0 = _fn0(name);
if (!_promise0 || !_promise0.then)
throw new Error('Tap function (tapPromise) did not return promise (returned' + _promise0 + ')');
_promise0.then(_result0 => {
_hasResult0 = true;
_next0();}, _err0 => {if (_hasResult0) throw _err0;
_error(_err0);
});
_sync = false;
});
即返回的是一个 promise