我有一些我想重构的代码(从控制器提取服务器通信方法到单独的服务)。
的示例:的
$http.post("/mypath", someData)
.success(function(request) {
if (request.ok) {
$scope.error = "";
_refreshAppointments();
}
else {
$scope.error = request.err;
}
})
.error(function() {
$scope.error = "Error during communicating to server";
});
我目前的问题是处理错误(与旧的$ scope通信)。所以我想抛出异常这样的行$scope.error = "Error during communicating to server";
并在控制器中抓住它们。
这是好主意吗?
答案 0 :(得分:3)
如果在vanilla环境中抛出错误:
setTimeout(function () {
throw new Error();
}, 1);
错误就会丢失。 (window.onerror
会看到它)
即使你这样做:
try {
setTimeout(function () {
throw new Error();
}, 1);
} catch (e) {
console.log(e);
}
你不会看到错误。
您需要包装每个异步事件,例如:
function mySetTimeout(callback, ms) {
setTimeout(wrap_in_try_catch(callback), ms);
}
mySetTimeout(function () {
throw new Error();
});
您现在可以在通用错误处理程序中捕获错误,但仍然无法在周围的代码中捕获它。
这就是Promises的用武之地。并非所有的库都以相同的方式(或正确地)做Promise,所以我不知道你的库支持有多好。
您的代码大致如下:
$.ajax().then(function () {
throw new Error();
}).fail(e) {
console.log("it failed!", e);
});
如果你有:
$.ajax().then(function () {
throw new Error();
}); // throws something like: no fail callback for rejected value error
然后你的全局错误处理程序将把它拿起来。这样可以确保没有任何错误可以通过裂缝而丢失。
让Promise库以这种方式处理错误并非不可能,但设置起来有点棘手。虽然你有这个,但你很好。错误处理变得轻而易举。
你再也不会写一个try-catch,只是一堆.fail()
个处理程序。
答案 1 :(得分:1)
将REST / http请求提取到模型/服务层并使用控制器中的这些服务绝对是个好主意。然后处理失败的操作意味着拒绝相应的承诺,在这种情况下,在promise中抛出异常实际上意味着相同。
例如,这就是您的服务/工厂的样子:
app.factory('dataService', function($http) {
return {
load: function() {
return $http.post("/mypath", someData).then(function(response) {
if (!response.data.ok) {
return throw new Error(response.request.err);
// or return $q.reject(response.request.err);
}
return response.request;
});
}
};
});
和消费控制器将处理承诺状态,已解决(成功)或拒绝(失败/异常):
dataService.load().then(function(request) {
$scope.error = "";
_refreshAppointments();
})
.catch(function(err) {
$scope.error = err || "Error during communicating to server";
});