全局标记控制
(1)简单计数器控制
也许上面介绍的异步方法仍然不能满足实际开发中的业务场景:假设我们有a(),b(),c()三个方法,a和b没有依赖关系,可以异步进行。但是c必须在a和b都完成之后才能触发。为满足这样的逻辑实现,我们加入一个全局计数器来控制代码的执行流程:
var flag=2; var aValue,bValue; function a(){ aValue=1; flag--; c(); } function b(){ setTimeout(function(){ bValue=2; flag--; c(); },200); } function c(){ if(flag==0){ console.log("after a and b:"+(aValue+bValue)); } } a(); b();
我们设置了一个全局变量flag来监控方法a和方法b的完成情况。方法b通过设置一个200毫秒的定时器来模拟网络环境,最终会在b方法执行完成之后成功调用c方法。这样我们就实现了对方法a(),b(),c()的依赖调用。
(2)面向数据的控制
当上述方案在复杂场景下应用时,会出现如下问题:产品经过多个版本迭代,c方法依赖更多的方法,因此计数器flag需要不断的变化;产品迭代过程中更换了开发人员。当出现上述两种情况时,代码的逻辑将会变得混乱不堪,flag标记符是否能保持简明正确很大程度上受到了产品迭代的影响。因此我们提出面向数据的优化改进。
在真实的开发场景中,存在方法依赖的原因基本都是因为存在数据依赖,对于上面那个简单的示例:c方法依赖于a方法和b方法操作的结果,而不是依赖于flag是否为0。因此我们可以通过检查依赖方法是否已经完成了数据处理来代替检查标记符是否已经被置为0,在这个例子中也就是在c方法中检查aValue和bValue是否已经完成了赋值:
function c(){ if(aValue!==undefined && bValue!==undefined){ console.log("after a and b:"+(aValue+bValue)); } }
针对更加通用的场景,我们将上述代码修改为下:
var checkDependency={}; var aValue,bValue; function a(){ aValue=1; checkDependency.a=true; c(); } function b(){ setTimeout(function(){ bValue=2; checkDependency.b=true; c(); },200); } function c(){ if(checkDependency.a && checkDependency.b){ console.log("after a and b:"+(aValue+bValue)); } } a(); b();
通过面向数据的检查方式,未来扩展时,我们仅需要在新增的方法中增加对checkDependency对象的修改,并且在c方法中检查相应属性的存在就能实现异步依赖方法的顺序执行。
Promise类
为了解决JavaScript中异步方法的复杂性,官方引入了一种统一的控制方式:
var bool=false; /* * 新建一个Promise实例,向构造函数传入一个异步执行函数 * 异步函数会接受两个参数,由Promise传入,对应then方法中传入的方法 */ var promise=new Promise(function(resolve,reject){ setTimeout(function(){ if(bool){ //根据执行情况相应调用resolve和reject resolve(bool); }else{ reject(bool); } },200); }); //通过then向Promise实例传入解决方法 promise.then(function resolve(result){ console.log("success"); },function reject(result){ console.log("failure"); });
上例代码展示了一个基础的Promise应用,也许实际场景中更加多见的是下面这种链式调用:
new Promise(function(res,rej){ if(/*异步调用成功*/){ res(data); }else{ rej(error); } }).then(function resolve(result){ console.log("success"); },function reject(result){ console.log("failure"); });
以上是javascript全局标记控制和Promise类用法实例详解的详细内容。更多信息请关注PHP中文网其他相关文章!