我想在浏览器端JavaScript代码中记录所有错误。我在这里和网上看到了很多关于window.onerror的讨论,很明显它不能跨浏览器工作。所以,我计划用try-catch包装顶级入口函数。麻烦的是,我的很多代码都是事件处理程序。我还没有测试过,但我很确定无论在何处定义事件处理函数,抛出的错误都会直接触发调用它的浏览器实现,而不是事件函数声明代码。我唯一的选择是在每个错误处理程序中声明throw,catch和error log调用,即使是最小的匿名调用。我不喜欢那一点。
可能的解决方案:
我使用一种方法来跨浏览器注册事件。我可以修改它来做这样的事情:
function registerEventHandler(object, handlerRef) {
var wrapperFunction = function(evt) {
try {
handlerRef(evt);
} catch {
logError(error);
}
registerEvent(object, wrapperFunction);
}
该实施存在一个主要问题。我经常保留对事件处理函数的引用,以便以后注销它们。这不起作用,因为作为处理程序注册的函数将是包装器,而不是原始包装器。答案是实现一个包装器 - >包装映射对象并在取消注册时使用它。
问题:
我敢让JavaScript魔术师想出更聪明的解决方案。也许它可以通过在注册之前以某种方式增强事件处理函数来完成?这是我的JavaScript知识。你的呢?
答案 0 :(得分:1)
我经常保留对事件的引用 处理函数以便 稍后取消注册。这不会 作为注册的功能工作 处理程序将是包装器,而不是 原来的。
为什么这是一个问题?一旦函数包含在错误处理中,你就不再关心原始函数了。包装器保留对原始函数的引用,包装器是注册的,包装器是需要取消注册的。
只需保留对您生成的包装函数的引用,因为它是唯一重要的函数。
同样使它成为自己的功能将使这种模式更加可重复使用
var protectErrors = function(fn) {
var that = this;
return function() {
try {
fn.apply(that, arguments);
} catch(error) {
logError(error);
}
};
};
var registerEventHandler = function(object, handlerRef) {
var wrapperFunction = protectErrors(handlerRef);
registerEvent(object, wrapperFunction);
};
protectErrors(fn)
将返回一个函数,该函数在调用它的任何上下文中运行原始函数,并转发任意数量的参数。