前段时间学习《深刻浅出Nodejs》时,在第四章 - 异步编程中做者朴灵曾提到,异步编程的难点之一是异常处理,书中描述"尝试对异步方法进行try/catch操做只能捕获当次事件循环内的异常,对call back执行时抛出的异常将无能为力"。编程
果真,项目测试过程当中,连续两天遇到了Node.js进程Crash的问题。经过Debug Log,究其缘由,发现正是书中提到的问题。异步
例如, 异步编程
1 //test.js 2 3 var test = undefined; 4 5 try{ 6 var f1 = function(){ 7 console.log(test.toString()); 8 } 9 } 10 catch(e){ 11 console.log('error..'); 12 } 13 14 //assume somewhere f1() will be called as an call back function 15 f1();
这里模仿f1函数是作为call back(回调)函数传递给其余函数,在其余函数执行过程当中执行call back的函数。从代码表面来看,很容易认为若是Line 7, 函数
1 console.log(test.toString());
若是这行code发生异常,会天然认为其会被try catch捕获到,并不会引发进程的Crash。但其实,运行结果是:学习
运行错误,Line 11的错误并无打印,说明在程序中错误没有被Try Catch。而Nodejs做为单进程单线程程序,将会引发进程的Crash!测试
------------------------------------------------------------------------------------------------------------------------spa
所以,在进行异步编程时,我的以为:线程
要考虑到call back函数可能产生的错误,增长类型检查代码或在Call back被真正执行的地方增长Try cach等,避免异常未能被捕获致使进程Crash
code
------------------------------------------------------------------------------------------------------------------------blog
如本例,可修改以下,
1 if(typeof(test) != 'undefined'){ 2 console.log(test.toString()); 3 }
或者
1 console.log(test? test.toString() : '[undefine]');
或者
1 try{ 2 f1(); 3 } 4 catch(e) 5 { 6 console.log('new error..'); 7 }
这样,再次运行程序,就能够避免异常,避免进程的Crash。
小结:
在Node.js中,很是多的异步调用API,在执行API,传入Call back函数时,必定要注意Call back函数里可能发生的错误,若是没有被正常的Try catch到或者其余方式避免,就有可能致使进程的Crash。
Best Regards
Kevin Song
2014/6/25