从异步方法抛出异常是正常的吗?

时间:2015-09-01 16:09:14

标签: javascript angularjs rest

我有一些我想重构的代码(从控制器提取服务器通信方法到单独的服务)。
示例:

$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"; 并在控制器中抓住它们。
这是好主意吗?

2 个答案:

答案 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";
});