用好js与nodejs中的try...catch
对异常的捕获和处理是提高程序鲁棒性的一个重要方式,即使在javascript/nodejs等看似“很难写出bug”的弱类型语言里,异常捕获处理仍至关重要,这主要是因为:
1.在一个代码块里,如果程序运行过程中自动、或主动(new Error/Exception)生成异常/错误后,若不主动去try...catch该异常,这个异常会逐层抛出,直至主程序,系统会按照框架默认方式处理该异常。
2.在逐层抛出异常的过程中,每层代码块异常点之后的程序不会再被执行,除非进行try...catch异常处理。
我们看几个简单的例子来验证一下。
(() => {
try{
(()=>{
nonExistentFunction();
console.log('c');
})();
console.log( 'b' );
}catch(e){
console.log( e );
}
})();
console.log( 'a' );
打印结果:
即,打印了最外层的catch内的异常处理信息和主程序接下来的部分,根据1,2可知,如果匿名函数最外层没有进行try...catch处理的话,a也不会被打印出来。
这意味着,即使是“很难写出bug”的javascript也可能因为一个小小的异常导致整个程序歇菜!try...catch则是保证主干按流程执行完毕的关键实现。
容易被误处理的异步异常
在nodejs等异步IO密集场景,经常用异步回调函数来处理IO操作结果——不管是正确的数据还是异常Error,但此时的try...catch怎么来写?
const fs = require('fs');
try{
fs.readFile( __dirname+'/15_fs1.js',(err,data) =>{
if( err ){
throw err;
}else{
console.log( data );
}
} );
}catch(err){
console.log( 'an error occured!',err );
} console.log( 'hhh' );
在文件不存在的情况下,按照try..catch的作用,我们认为应该在catch里捕捉到异常并执行异常处理语句,即打印“an error occured!XXX”;但实际结果呢?
即,异常最后并未被目前缩写的catch所捕获,而是最终被系统级捕获并按照框架方式打印出了错误信息,这是为什么呢?主要是因为try...catch是代码块,是被同步解析的,当代码执行到try后,开始读文件操作,等待异步执行结果,但catch语句是紧接着try进行的,它并不会等待异步执行的结果,因此,当执行到catch的时候,回调里的throw error还没执行呢,当然catch不到了,主程序继续解析执行直到打印出'hhh'。随后当异步会调离throw err的时候没有catch可以捕获的到,只能层层抛出到最外层,由框架来捕获和执行。
理解上述内容后,就该想到问题的关键点是try...catch的执行ticker与回调函数ticker不同步的问题,解决的办法也很简单,同步try...catch与callback函数的时钟—将try..catch放在callback里面。
正确的代码示例:
const fs = require('fs'); fs.readFile( __dirname+'/15_fs1.js',(err,data) =>{
try{
if( err ){
throw err;
}else{
console.log( data );
}
}catch(e){
console.log( e );
}
} );
console.log( 'hhh' );
打印结果:
19年要在使用新框架写好业务逻辑的基础上,提高自己输出代码的鲁棒性,经常去分析、反思可能出现异常的模块并进行forecast error的捕获处理,进一步提高自己的代码水平。
——学无止境,保持好奇。May stars guide your way.
用好js与nodejs中的try...catch的更多相关文章
- 原声js实现nodejs中qs模块中的parse和stringfiy方法
function stringify(obj, sep, eq) { sep = sep || '&'; eq = eq || '='; let str = ""; for ...
- Node.js学习笔记(二) --- CommonJs和Nodejs 中自定义模块
一. 什么是 CommonJs? JavaScript 是一个强大面向对象语言,它有很多快速高效的解释器. 然而, JavaScript标准定义的 API 是为了构建基于浏览器的应用程序.并没有制定一 ...
- 在python中调用js或者nodejs
在python中调用js或者nodejs要使用PyExecJs第三方包. pip install pyexecjs 示例代码 >>> import execjs >>&g ...
- 在Nodejs中如何调用C#的代码
最近需要在Nodejs中用到C#的代码,从网上了解到可以采用Edgejs来实现Nodejs与C#的代码交互, 直接复制网上的代码运行总是出各种错,填了不少坑,现在把自己的案例代码大致整理一下,方便以后 ...
- NodeJS中的异步I/O、事件驱动
nodejs的主要特点是单线程.异步I/O.事件驱动.让我们先大概了解一下这些名词的意思. 单线程 单线程是任务按照顺序执行的,并且每次只执行一个任务,只有前面的任务执行完成以后,后面的任务才执行.在 ...
- 探讨Nodejs中的作用域问题。
在JS中有全局作用域和函数作用域,而在Nodejs中也自己的作用域,分为全局作用域(global)和模块作用域. js作用域: 以前学js的时候我们的全局对象是window,如: var a = 10 ...
- nodejs中exports与module.exports的实践
只要是在nodejs中写自己的文件模块就少不了会遇到module.exports和exports的使用,看别人的代码大多都会使用“module.exports=exports=<对象/函数等&g ...
- 详细讲解nodejs中使用socket的私聊的方式
详细讲解nodejs中使用socket的私聊的方式 在上一次我使用nodejs+express+socketio+mysql搭建聊天室,这基本上就是从socket.io的官网上的一份教程式复制学习,然 ...
- nodejs中常用加密算法
在常用的nodejs+express工程中,为了安全在登录及表单传输时,应该都需进行加密传输,目前个人常用到的加密方式有下列几种: 1.Hash算法加密: 创建一个nodejs文件hash.js,输入 ...
随机推荐
- Linux wpa_cli 调试方法
记录一下如何使用wpa_cli来进行wifi调试. 1.启动WLAN (1)加载驱动 打开wifi的时候会加载驱动,关闭则会卸载wifi驱动.手动调试的时候,先调用insmod/rmmod命令加载/ ...
- uiautomator2.0框架
1. Uiautomator1.0 Uiautomator2.0 date 2012 2015 super class UiAutomatorTestCase InstrumentationTes ...
- CSS3:CSS 听觉参考手册
ylbtech-CSS3:CSS 听觉参考手册 1.返回顶部 1. 听觉样式表 听觉样式表可把语音合成与音响效果相组合,使用户可以听到信息,而无需进行阅读. 听觉呈现可用于: 视觉能力低弱的人士 帮助 ...
- Codeforces Round #408( Div2)
Bank Hacking 阅读题,读完之后手算一下可以发现每一个bank被hack所需要的strength无非分为三种情况. 1. $a_i$,当且仅当i为第一个选择的点. 2. $a_i+1$,当且 ...
- linux中的条件变量
1 大家可能知道互斥量是线程程序中必须的工具了,但是也不能是万能的,就比如某个线程正在等待共享数据某个条件的发生,这个时候会发生什么呢.它就可能重复的尝试对互斥对象锁定和解锁来检查共享数据结构. 2 ...
- struts2 中的 addActionError 、addFieldError、addActionMessage的方法
addActionError .addFieldError.addActionMessage都是ActionSupport的方法 一.addActionError("错误内容"): ...
- python---socket与socketserver
1.socket的方socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0) #获取要连接的对端主机地址sk.bind(ad ...
- 《剑指offer》面试题17—合并两个排序链表
题目:输入两个递增排顺序的链表,合并这两个链表并使合并后的链表仍是递增排序的. 重点: 1.代码鲁棒性:要判断输入的两个链表都为NULL:其中一个链表为NULL的情况. 2.用递归实现,注意递归的思路 ...
- js 调用栈机制与ES6尾调用优化介绍
调用栈的英文名叫做Call Stack,大家或多或少是有听过的,但是对于js调用栈的工作方式以及如何在工作中利用这一特性,大部分人可能没有进行过更深入的研究,这块内容可以说对我们前端来说就是所谓的基础 ...
- throw UnsupportedOperationException
package org.usc.action; import java.util.ArrayList; import java.util.Arrays; import java.util.List; ...