【问题标题】:Using chained promises ($q) to make $http使用链式承诺 ($q) 生成 $http
【发布时间】:2014-09-30 16:45:54
【问题描述】:

我有想要“重新验证”的数据。所以我需要发出一个get请求,保存回调中的数据,删除当前数据,然后用回调中的数据发布一个帖子。

我需要以某种方式使用 $q。

也许我完全不在了,但这就是我尝试过的。

$scope.reSaveBIM = function(){

  var defer = $q.defer();

  defer.promise
    .then(function(){
      $http.get('/api/bim/' + $scope.activePartOfBim._id)
        .success(function(fullBIM){
          console.log(fullBIM); //Defined
          return fullBIM;
        }
      );
    })
    .then(function(fullBIM){
      console.log(fullBIM); //Undefined
      $http.delete('/api/bim/' + $scope.activePartOfBim._id);
      return fullBIM
    })
    .then(function(fullBIM){
      $http.post('/api/bim', {bim:JSON.stringify(fullBIM)});
    });

  defer.resolve()

};

第一个回调的数据不会在链中返回。我在正确的轨道上吗?我也尝试使用 $q.all 但失败了。

有什么想法吗?

【问题讨论】:

    标签: angularjs angular-promise


    【解决方案1】:

    无需创建额外的$q.defer 对象,您可以简单地将$http 返回的promise 链接起来...

    $scope.reSaveBIM = function() {
        return $http.get('/api/bim/' + $scope.activePartOfBim._id).then(function(response) {
            var fullBIM = response.data;
            return fullBIM;
        }).then(function(fullBIM) {
            return $http.delete('/api/bim/' + $scope.activePartOfBim._id).then(function() {
                return fullBIM;
            });
        }).then(function(fullBIM) {
            return $http.post('/api/bim', { bim:JSON.stringify(fullBIM) }).then(function() {
                return fullBIM;
            });
        }).catch(function(response) {
            // return an error message using throw
            throw "Something went wrong - Status " + response.status;
        });
    };
    

    叫它……

    $scope.reSaveBIM().then(function(fullBIM) {
        console.log('success! fullBIM: ', fullBIM);
    }, function(errorMsg) {
        console.log(errorMsg);
    });
    

    【讨论】:

      【解决方案2】:

      你几乎是对的,你不需要defer。而不是success 使用then。我认为成功不会回报承诺。 $http then 成功回调在 response.data 属性中也有 data

      【讨论】:

        【解决方案3】:

        AngularJS 的 $http 已经包装了 $q 服务。 From the documentation

        $http API 基于 $q 服务公开的延迟/承诺 API。

        本质上,您的问题是 $http 使用的承诺与您使用 $q 创建的承诺不同。你需要链接你的 $http 调用来做同样的事情。事实上,你已经在使用来自 $q 的 Promise。

        此外,您可以通过声明函数并将它们作为变量传入来解决此问题。

        $http.get('/api/bim/' + $scope.activePartOfBim._id)
            .success(firstSuccessFunction);
        
        var firstResponse;
        var firstSuccessFunction = function(fullBIM){
          console.log(fullBIM); //Defined
          firstResponse= fullBIM;
          $http.delete('/api/bim/' + $scope.activePartOfBim._id)
                  .success(secondSuccessFunction);
        };
        
        var secondSuccessFunction = function(deleteResponse) {
          $http.post('/api/bim', {bim:JSON.stringify(firstResponse)});
        };
        

        【讨论】:

        • 当然我可以建立一个金字塔,但我想学会用承诺把它弄平。
        • $http 已经在 Promise 上运行。 .success() 等价于 .then()。如果你想扁平化你的代码,那么你不应该内联你的响应函数。尝试将函数作为参数传递给成功方法,即 .success(mySuccessFunction);
        • 有一个微妙的问题...firstSuccessFunction 在传递给.success(firstSuccessFunction) 时是undefined
        猜你喜欢
        • 2013-05-02
        • 2015-04-15
        • 2017-08-12
        • 2016-04-24
        • 1970-01-01
        • 1970-01-01
        • 2015-04-08
        • 2015-02-04
        • 2014-10-31
        相关资源
        最近更新 更多