Effective JavaScript Item 63 注意异步调用中可能会被忽略的异常
异常处理是异步编程的一个难点。
在同步的代码中,异常可以非常easy地通过try catch语句来完毕:
try {
    f();
    g();
    h();
} catch (e) {
    // handle any error that occurred...
}
可是在异步代码中,使用一个try代码块将全部可能出现的异常都包含在内是不现实的。实际上,异步API设置不能抛出异常。由于当异常发生时,通常已经没有运行上下文供它抛出了。
全部,在异步API中一般会使用特殊的參数或者错误回调函数来表示异常信息。比方。在Item
 61中提到的下载文件的异常处理能够例如以下进行:
downloadAsync("http://example.com/file.txt", function(text) {
    console.log("File contents: " + text);
}, function(error) {
    console.log("Error: " + error);
});
可见downloadAsync方法不仅接受了一个作为成功返回响应时的回调函数。同一时候还接受了一个异常回调函数。那么以此类推,在下载多个文件时的异常处理是这种:
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) { // repeated error-handling logic
        console.log("Error: " + error);
    });
}, function(error) { // repeated error-handling logic
    console.log("Error: " + error);
});
第一眼看上去。上述代码有些乱。所以我们能够考虑使用命名回调函数的方式将错误处理抽取出来:
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);
在Node.js中。另一种异常处理API的风格。它会将错误信息作为回调函数的第一个參数。假设没有错误发生,那么该參数的值是null,undefine之类的falsy值。使用这样的方式进行异常处理例如以下所看到的:
function onError(error) {
    console.log("Error: " + error);
}
downloadAsync("a.txt", function(error, a) {
    if (error) {
        onError(error);
        return;
    }
    downloadAsync("b.txt", function(error, b) {
        // duplicated error-checking logic
        if (error) {
            onError(error);
            return;
        }
        downloadAsync(url3, function(error, c) {
            // duplicated error-checking logic
            if (error) {
                onError(error);
                return;
            }
            console.log("Contents: " + a + b + c);
        });
    });
});
为了添加代码的可读性。非常多开发者会省略用于推断是否须要异常处理的if语句块的大括号:
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(url3, function(error, c) {
            if (error) return onError(error);
            console.log("Contents: " + a + b + c);
        });
    });
});
在使用异步API时。忘记对异常进行处理是常常犯的错误。这会让异常信息被忽略掉,从而导致比較糟糕的用户体验。所以在使用异步API时,切记对异常情况进行处理。我想这也是为何在Node.js中,异常信息会被当做回调函数的第一个參数,让开发者不得不面对它。
总结
- 避免对异常处理代码进行复制粘贴,将它作为共享的函数是更好的选择。
- 确保对异常情况进行处理,避免对异常的忽略。
Effective JavaScript Item 63 注意异步调用中可能会被忽略的异常的更多相关文章
- [置顶] Ajax程序:处理异步调用中的异常(使用Asp.Net Ajax内建的异常处理方法)
		无论在Window应用程序,还是Web应用程序以对用户友好的方式显示运行时的异常都是很有必要,尤其对于可能有很多不确定因素导致异常的Web应用程序;在传统的Web开发中,处理异常的方式——设计专门一个 ... 
- [知识库:python-tornado]异步调用中的上下文控制Tornado stack context
		异步调用中的上下文控制Tornado stack context https://www.zouyesheng.com/context-in-async-env.html 这篇文章真心不错, 非常透彻 ... 
- Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表
		本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ... 
- Effective JavaScript Item 38 调用父类的构造函数在子类的构造函数
		作为这一系列Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中.都会有场景(Scene)这一概念.在一个场景中会包括一个对象集合,这些对象被称为角色(Actor). ... 
- Effective JavaScript Item 39 绝不要重用父类型中的属性名
		本系列作为Effective JavaScript的读书笔记. 假设须要向Item 38中的Actor对象加入一个ID信息: function Actor(scene, x, y) { this.sc ... 
- Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合
		本系列作为Effective JavaScript的读书笔记. ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 可是在使用for..in循环对Objec ... 
- Effective JavaScript Item 37 认识this的隐式指向
		本系列作为Effective JavaScript的读书笔记. CSV数据通常都会被某种分隔符进行分隔.所以在实现CSV Reader时,须要支持不同的分隔符.那么,非常自然的一种实现就是将分隔符作为 ... 
- Effective JavaScript Item 10 避免使用with
		本系列作为Effective JavaScript的读书笔记. Item 9:避免使用withkeyword 重点: 设计withkeyword本来是为了让代码变简洁,可是却起到了相反的效果.比方: ... 
- Effective JavaScript Item 22 使用arguments来创建接受可变參数列表的函数
		本系列作为Effective JavaScript的读书笔记. 在Item 21中,介绍了结合apply方法实现的可变參数列表函数average,它实际上仅仅声明了一个数组作为參数,可是利用apply ... 
随机推荐
- codeforces round #257 div2 C、D
			本来应该认真做这场的.思路都是正确的. C题,是先该横切完或竖切完,无法满足刀数要求.再考虑横切+竖切(竖切+横切), 由于横切+竖切(或竖切+横切)会对分割的东西产生交叉份数.从而最小的部分不会尽可 ... 
- The .NET weak event pattern in C#
			Introduction As you may know event handlers are a common source of memory leaks caused by the persis ... 
- CentOS 安装 Jenkins
			原文:https://www.sunjianhua.cn/archives/centos-jenkins.html 1.更换源 mv /etc/yum.repos.d/CentOS-Base.repo ... 
- 查询 EBS 系统物料净重、毛重
			/* Formatted on 2018/3/14 23:40:47 (QP5 v5.256.13226.35538) */ SELECT DISTINCT MSI.SEGMENT1 || ',' 物 ... 
- SQL 参考
			本主题将介绍 ArcGIS 中的选择表达式所用的常规查询的各个元素.ArcGIS 中的查询表达式使用常规 SQL 语法. 警告: SQL 语法不适用于使用字段计算器计算字段. 字段 在 SQL 表达式 ... 
- Swift - transform.m34动画示例
			Swift - transform.m34动画示例 效果 源码 https://github.com/YouXianMing/Swift-Animations // // CATransform3DM ... 
- Eclipse 离线汉化的方法
			本文感谢:http://jingyan.baidu.com/article/e75057f28401a8ebc91a899e.html 首先进入网址:http://www.eclipse.org/ba ... 
- Eclipse启动时提示Fail to create the Java Virtual Machine的解决方法
			这个错误是Eclipse里面的一个bug,我们通过如下的设置就可以解决它. 打开eclipse安装目录下的eclipse.ini文件: 将其中的256m改为128m,512m改为256m,1024m改 ... 
- [Web 前端]   解决因inline-block元素导致的空白间距和元素下沉
			cp from : https://www.jianshu.com/p/617e78a27c88 ** 前言: ** CSS 中的 display:inline-block 是笔者最为喜欢的元素之一, ... 
- java HttpServletRequest和HttpServletResponse詳解
			這篇文章主要介紹瞭java HttpServletRequest和HttpServletResponse詳解的相關資料,需要的朋友可以參考下 java HttpServletRequest和HttpS ... 
