【问题标题】:chain controller functions/code in sequential order and handle errors按顺序链接控制器功能/代码并处理错误
【发布时间】:2016-10-21 15:45:09
【问题描述】:

我有一些用于不同任务的控制器函数,它们可能会调用服务函数(这些函数又包含 $http 请求)。例如:

// this should be run first
function getData1(request) {
    dataService.getData1(request).then(function success(response) {
        return response;
    })
};

// this should run after getData1()
function getData2(request) {
    dataService.getData2(request).then(function success(response) {
        return response;
    })
};

我在某个事件的中心位置调用这些函数(例如,当用户更改输入/请求数据时):

$scope.loading = true;
$scope.$watch('input', function(newValue, oldValue) {
    if(newValue !== oldValue) {
        request = newValue;
        $scope.data1 = getData1(request);
        $scope.data2 = getData2(request);
        $scope.loading = false;
    }
});

但据我所知,getData1()getData2() 发出异步请求,可能会在数据加载之前导致$scope.loading = false

另外,如果一个或多个请求中有任何错误,$scope.data1$scope.data2 变量将具有被拒绝的 Promise 值,对吧?

那么,链接这些函数并处理错误(如果有)的“最佳实践”是什么?请帮忙。

【问题讨论】:

  • 你可以做一个回调链,即在getData1()的回调中调用getData2()。这是最简单的方法。但是对于更复杂的用途,你可以考虑使用 Promise。
  • 我不想使用回调链。它使 getData2() 调用依赖于 getData1()。我想分离关注点,即从一个中心位置控制这种链接。
  • 如果不想使用回调,可以尝试使用promise,或者一些es6的特性比如async/await

标签: angularjs angular-promise


【解决方案1】:

getData1 and getData2(依次调用$http)返回promise

var promise1 = dataService.getData1(request);
var promise2 = dataService.getData2(request);

您可以使用$q.all()。将promise1promise2 传递给$q.all。这并不能保证promise 会按顺序解决。

If one promise fails, the combined promise fails.
If all promises succeed, the combined promise succeeds.

example link for $q.all

对于顺序执行,

dataService.getData1(request1).then(function(response1) {
    //do your stuff
    return dataService.getData2(request2);
}).then(function(response2) {
    //response2 - response of dataService.getData2(request2)
    //do your stuff
}).catch(function(error) {
    //on error if any of this fails.
})

【讨论】:

  • 我没有从 getData1() 返回一个承诺。要回报一个承诺,我必须做return dataService.getData1(request).then(function success(response) { return response; })
  • 但是我需要依次调用控制器函数getData1()getData2()。因为在这些调用之间我还有其他任务要做。我想将数据获取操作放在单独的函数中,以便我也可以轻松地对它们进行单元测试。将它们放在变量promise1promise2中并不能解决顺序调用的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-13
  • 1970-01-01
  • 2013-11-05
  • 2016-09-21
  • 1970-01-01
  • 2021-12-24
  • 2019-01-27
相关资源
最近更新 更多