One of the management of asynchronous programming is error handling. In synchronous code, it is easy to handle all errors at once by wrapping a piece of code with a try statement block.
try{ f(); g(); h();} catch(e){ //这里用来下得出现的错误}
Try statement block
However, for asynchronous code, multi-step processing is usually separated into separate rounds of the event queue, so it is not possible to wrap them in a try statement block. In fact, the asynchronous API is not even possible to throw an exception, because when an asynchronous error occurs, there is no obvious execution context to throw an exception! Instead, the asynchronous API tends to represent the error as a specific parameter to the callback function, or to use an additional error-handling callback function. For example, an asynchronous API that involves downloading files may have an additional callback function to handle network errors.
downloadAsync(‘http://cnblogs.com/wengxuesong‘,function(text){ console.log(‘file contents:‘+text);},function(error){ console.log(‘error:‘+error);});
If you download more than one file, you can use a callback function to nest it, as you would say in 62.
downloadAsync(‘a.txt‘,function(a){ downloadAsync(‘b.txt‘,function(b){ downloadAsync(‘c.txt‘,function(c){ console.log(‘Contents:‘+a+b+c); },function(error){ console.log(‘error:‘+error); }); },function(error){ console.log(‘error:‘+error); });},function(error){ console.log(‘error:‘+error);});
Each step of the code above uses the same error-handling logic, but we repeat the same code in multiple places. In the field of programming, you should try to keep your code from repeating. The duplication of code is abstracted by defining an error-handling function in the shared scope.
function onError(error){ console.log(‘Error:‘+error);}downloadAsync(‘a.txt‘,function(a){ downloadAsync(‘b.txt‘,function(b){ downloadAsync(‘c.txt‘,function(c){ console.log(‘Contents:‘+a+b+c); },onError); },onError);},onError);
If you use the tool function Downloadallasync to combine multiple steps into a single composite operation, you only need to provide a callback function for error handling.
downloadAllAsync([‘a.txt‘,‘b.txt‘,‘c.txt‘],function(abc){ console.log(‘Contents:‘+abc[0]+abc[1]+abc[2]);},function(error){ console.log(‘Error:‘+error); });
callback function Error Arguments
Another type of error-handling API is used by the node. JS platform. This style only requires a callback function, and the first parameter of the callback function indicates an error if an error occurs. Otherwise, it is a false value, such as null. For this type of API, we can define a common error-handling function that requires the use of an if statement to control each callback function.
function onError(error){ console.log(‘Error:‘+error);}downloadAsync(‘a.txt‘,function(error,a){ if(error){ onError(error); return; } downloadAsync(‘b.txt‘,function(error,b){ if(error){ onError(error); return; } downloadAsync(‘c.txt‘,function(error,c){ if(error){ onError(error); return; } console.log(‘Contents:‘+a+b+c); }); });});
Programmers typically discard the IF statement and use the brace structure to span multiple lines of convention to make error handling more concise and more focused.
function onError(error){ console.log(‘Error:‘+error);}downloadAsync(‘a.txt‘,function(error,a){ if(error)return onError(error); downloadAsync(‘b.txt‘,function(error,b){ if(error)return onError(error); downloadAsync(‘c.txt‘,function(error,c){ if(error)return onError(error); console.log(‘Contents:‘+a+b+c); }); });});
You can also use an abstract merge step to help eliminate duplicates
var filenames=[‘a.txt‘,‘b.txt‘,‘c.txt‘];downloadAllAsync(filenames,function(error,abc){ if(error){ console.log(‘Error:‘+error); return; } console.log(‘Contents:‘+abc[0]+abc[1]+abc[2]);});
One practical difference between the Try...catch statement and the typical error-handling logic in the asynchronous API is that the try statement makes it easy to define a "catch all" logic that can easily cause the programmer to forget the error handling of the entire code area. and the asynchronous API given above is very easy to forget to provide error handling in any step of the process. This causes the error to be discarded. Ignoring the error-handling program can make the user very frustrated: there is no feedback when the application goes wrong. Similarly, the default error is not good for debugging. Because there is no clue to the source of the problem. It is best to be defensive, using asynchronous APIs that require vigilance to ensure that all error state conditions are handled explicitly.
Tips
[Effective JavaScript note] 63rd: Beware of discarding errors