Global mark control
(1) Simple counter control
Perhaps the asynchronous method introduced above still cannot meet the business scenario in actual development: Suppose we have a (), b(), c() three methods, a and b have no dependency and can be performed asynchronously. But c can only be triggered after both a and b are completed. In order to meet such a logical implementation, we add a global counter to control the execution flow of the code:
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();
We set a global variable flag to monitor the completion of method a and method b. Method b simulates the network environment by setting a 200 millisecond timer, and will eventually call method c successfully after method b is executed. In this way, we implement dependent calls to methods a(), b(), c().
(2) Data-oriented control
When the above solution is applied in complex scenarios, the following problems will occur: the product has gone through multiple version iterations, and the c method relies on more methods, so The counter flag needs to be constantly changed; developers are changed during the product iteration process. When the above two situations occur, the logic of the code will become confusing. Whether the flag tag can remain concise and correct is largely affected by product iterations. Therefore, we propose data-oriented optimization improvements.
In real development scenarios, the reason for the existence of method dependencies is basically because of the existence of data dependencies. For the simple example above: method c depends on the results of method a and method b, and It does not depend on whether flag is 0. Therefore, we can replace checking whether the marker has been set to 0 by checking whether the dependent method has completed data processing. In this example, we check whether aValue and bValue have completed assignment in the c method:
function c(){ if(aValue!==undefined && bValue!==undefined){ console.log("after a and b:"+(aValue+bValue)); } }
For a more general scenario, we modify the above code to the following:
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();
Through the data-oriented inspection method, when expanding in the future, we only need to add modifications to the checkDependency object in the new method. And by checking the existence of the corresponding attributes in the c method, the sequential execution of asynchronous dependent methods can be realized.
Promise class
In order to solve the complexity of asynchronous methods in JavaScript, the official introduced a unified control method:
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"); });
The above example code A basic Promise application is shown. Perhaps the following chain call is more common in actual scenarios:
new Promise(function(res,rej){ if(/*异步调用成功*/){ res(data); }else{ rej(error); } }).then(function resolve(result){ console.log("success"); },function reject(result){ console.log("failure"); });
The above is the detailed content of Detailed explanation of JavaScript global tag control and Promise class usage examples. For more information, please follow other related articles on the PHP Chinese website!