我过去常常抛出一些错误类的实例,让它们被应用到应用程序的某个地方,以解决用户错误。
示例可能是验证用户名:
function validateUsername (username) {
if (!/^[a-z0-9_-]{3,15}$/.test(username)) {
throw new ValidationError('Please enter 3-15 letters, digits, -, and/or _.');
}
}
$('#username').blur(function () {
try {
validateUsername($(this).val());
} catch (x) {
$('<p></p>').addClass('error').text(x).insertAfter(this);
}
});
但是现在我意识到我不能将这些相同的做法用于异步调用。例如:
function checkUsernameAvailability (username) {
$.get('/users/' + username).done(function () {
// Done = user returned; therefore, username is unavailable
// But I can't catch this error without resorting to something gross
// like window.onerror
throw new ValidationError('The username you entered is already in use.');
});
}
我可以让checkUsernameAvailability
接受回调和/或返回一个承诺,让它使用用户名的可用性执行所述回调。
$('#username').blur(function () {
checkUsernameAvailability(username, function (available) {
!available && alert('The username you entered is already in use.');
});
});
但是,使异常如此强大的一部分原因是它们可以冒泡堆栈直到它们被捕获,而如果我有另一个函数调用另一个调用checkUsernameAvailability
的函数,我需要通过这个回调的结果一直手动,直到我到达我想要处理它的地方。
将错误传递到堆栈的哪些替代方法有哪些?我可以想到其中一些,但没有一个像原生的例外一样干净:
checkUsernameAvailability
函数,成功回调和错误回调;这似乎与前一点有相同的缺点return false;
,以便它不会在堆栈中执行更高;但是,这会污染事件命名空间,并且可能会使其不清楚首先执行哪个事件侦听器;此外,使用控制台答案 0 :(得分:0)
原则上就像这样
function Exception (errcode) {
this.code = errcode;
}
...
try {
...
throw new Exception('alpha');
...
} catch (e) {
if (e.code === {something}) {
}
}
答案 1 :(得分:0)
如果它有所帮助,我最近在C中为UNIX编写了第一个用于UNIX的Rogue游戏,并将其重写为javascript以在浏览器中工作。我使用了一种名为continuation的技术,能够等待用户输入密钥,因为在javascript中没有中断。
所以我会有一段这样的代码:
void function f() {
// ... first part
ch = getchar();
// ... second part
}
将在
中转换function f() {
// ... first part
var ch = getchar(f_cont1);
return;
// the execution stops here
function f_cont1 () {
// ... second part
}
}
然后存储继续以在keypressed事件上重用。有了闭包,一切都会在停止的地方重新启动。