Appearance
SyncBailHook
串行同步熔断执行
特点
- 串行同步执行
- 如果事件处理函数执行时有一个返回值不为空(即返回值为 undefined),则跳过剩下未执行的事件处理函数(如类的名字,意义在于保险)
源码分析
我们看 SyncBailHook 的 content
js
return this.callTapsSeries({
onError: (i, err) => onError(err),
/*
if (_result0 !== undefined) {
return _result0;
} else {
// next() 执行下一个事件流的代码生成函数,并将生成的代码放在此处
}
*/
onResult: (i, result, next) => `if(${result} !== undefined) {\n${onResult(result)};\n} else {\n${next()}}\n`,
onDone,
rethrowIfPossible,
})
其在 this.callTap() 的过程也是一样的,只是在最后
js
if (onResult) {
code += onResult(`_result${tapIndex}`)
}
处理 _result 的时候不同
同样我们先看生成的代码
js
// new Function('name,age', ``);
;("use strict")
debugger
var _context
var _x = this._x
var _taps = this.taps
var _interceptors = this.interceptors
_interceptors[0].call(name, age)
var _tap0 = _taps[0]
_interceptors[0].tap(_tap0)
var _fn0 = _x[0]
var _result0 = _fn0(name, age)
if (_result0 !== undefined) {
return _result0
} else {
var _tap1 = _taps[1]
_interceptors[0].tap(_tap1)
var _fn1 = _x[1]
var _result1 = _fn1(name, age)
if (_result1 !== undefined) {
return _result1
} else {
var _tap2 = _taps[2]
_interceptors[0].tap(_tap2)
var _fn2 = _x[2]
var _result2 = _fn2(name, age)
if (_result2 !== undefined) {
return _result2
} else {
var _tap3 = _taps[3]
_interceptors[0].tap(_tap3)
var _fn3 = _x[3]
var _result3 = _fn3(name, age)
if (_result3 !== undefined) {
return _result3
} else {
var _tap4 = _taps[4]
_interceptors[0].tap(_tap4)
var _fn4 = _x[4]
var _result4 = _fn4(name, age)
if (_result4 !== undefined) {
return _result4
} else {
var _tap5 = _taps[5]
_interceptors[0].tap(_tap5)
var _fn5 = _x[5]
var _result5 = _fn5(name, age)
if (_result5 !== undefined) {
return _result5
} else {
}
}
}
}
}
}
// 可以看出相对于 syncHook 其实现串行的方式就是
// var _result1 = _fn1(name, age);
// if (_result1 !== undefined) {
// return _result1;
// } else {
// }
// 将不为空的回调返回值去覆盖第一个参数
从上面可以看出,tapable 实现串行(如果事件处理函数执行时有一个返回值不为空(即返回值为 undefined),则跳过剩下未执行的事件处理函数(如类的名字,意义在于保险))的方式是 var _result1 = _fn1(name, age);
将下一个事件流的执行代码生成到 if(_result1 !== undefined) { }
中