有没有这么一个场景,你的一个动做须要在全部异步方法执行完毕后,再进行操做?然而你对异步方法什么时候执行完毕感到困扰,只能在每一个方法中写回调,在回调中重复劳动?数组
偶然的,想起了以前经理讲过的闭包的概念,偶然的,以为能够应用到代码中。闭包
例如在某个动做的时候须要触发三个异步方法,他们为a(),b(),c()。咱们在d()方法中执行a,b,c。而后在三个方法执行后须要抛出一个动做,然而咱们怎么知道这三个异步方法何时执行完呢?而且准确的在执行完的最后那个方法后抛出这个动做呢?异步
//异步a
function a(cb){
.....
if(cb)cb();
}
//异步b
function b(cb){ .....
if(cb)cb(); } //异步c function c(cb){ .....
if(cb)cb(); } //动做 function action(){ ... } //调用者 function main(){ a(); b(); c(); action(); }
本来我是用一个全局变量count记录执行次数,在每一个方法的回调中将执行次数减去。当有一个回调方法内的count被减为0的时候,就证实方法都执行完毕了。函数
var count=3;
//异步a
function a(){ ..... if(--count<=0){ action(); } } //异步b function b(){ ..... if(--count<=0){ action(); } } //异步c function c(){ ..... if(--count<=0){ action(); } } //调用者 function main(){ a(); b(); c(); //action(); }
是的,这个方法是能实现的,可是这个方法有点弊端,首先count是个固定值,你必须事先知道有多少个方法要执行,就是要本身数,若是新加了方法,那还要从新改变count的值,很明显这和咱们的'开放-关闭'原则是背道而驰的。其次每一个方法都要写一串相同的代码,复用性过低,重复性代码太多。最后,每一个方法都要访问全局变量,这增长了全局资源,用咱们经理说过的话,就是由于方法内的逻辑污染了到外部或全局代码。性能
明白了这样写的弊端,天然是要改了。 优化
《代码大全》中对'表查询法'有着很高的评价,即简洁了代码,又增长了可读性,在一些场景中甚至是提升代码性能的利器,咱们何不利用?spa
initFun:function(){ //初始化
var funArr = [a, b, c]; funArr.forEach(function (item) { item(); }) }
好了,接下来如何用闭包实现准确在三个方法执行后调用回调?code
在这以前,咱们先看看闭包的特性:访问外部变量,保持外部变量。blog
访问外部变量就是能在方法内访问外部变量,参数,局部变量或函数。保持外部变量是指把访问的外部变量拘留在这个方法的上下文中,每次调用方法都会带着这个上下文。简单来讲就是把咱们访问的这个外部变量存储在了这个方法的内存中,相似自带一个全局变量同样。内存
那么咱们该如何应用到代码中呢?
//异步a
function a(cb){
.....
if(cb)cb();
}
//异步b
function b(cb){ .....
if(cb)cb(); } //异步c function c(){ .....
if(cb)cb(); }
...... //闭包调用 function closureFun(closureCount, closureCb) {var count = closureCount; var callback = closureCb; return function () { if (!--count) { callback(); } } }, //初始化 function initFun(){
var funArr = [a, b, c]; //执行完全部异步方法后的回调方法 var callBack = function () { console.log('i am callback'); } //注册闭包代码 var testClosureFun = me.methods.closureFun(funArr.length, callBack); funArr.forEach(function (item) { item(testClosureFun); }) },
初始化方法中参照表查询法,将方法暂留在一个数组中,写好回调方法,并将其注册到闭包方法。funArr.length是这个闭包方法访问的外部变量,是闭包内部判断后最终将运行的次数,每次运行完一个方法,数量减一,当全部方法执行完毕,count也就为0了,这时候就会调用回调方法。
这段代码没有污染到全局,方法的数量也自动计算,每一个方法中抽离了重复代码,也算是优化了点吧。
虽然这不必定是最好的选择,但能在偶然间把本身学到的知识应用到实际中,成就感天然也是满满的。
固然这优化手段有什么缺陷或不足,望能指出,若是有更好的重构方案,有人知道并能指点一二,那也是鄙人的荣幸了。