首页 文章

如何使用$ q多次回调AngularJs中的承诺?

提问于
浏览
2

我正在使用下面的代码来简化后端请求,但我没有 grab 如何调用成功方法或错误方法 .

如何达到代码中注释的预期行为?

app.factory('REST', function ($http, $q, sweetAlert) {

    return {
        load: function (module, action, data) {
            var deferred = $q.defer();
            var promise = deferred.promise;         
            $http
            .post('/api/'+module+'.php?action='+action, data)
            .success(function (data) {

                if(data.error)
                {
                    sweetAlert.swal({
                        title: "Error",
                        text: data.error,
                        type: "warning"
                    });
                //HERE I WANT TO CALL .error(details)
                }
                else
                    deferred.resolve(data.result);

                        }).error(function () {
                //HERE I WANT TO CALL .error(details)
            });

            promise.success = function(fn) {
                promise.then(fn);
                return promise;
            }

            return promise;
        }
    };
});

这是使用上面代码的代码:

$scope.login = function () {
    $scope.loading = true;
    var payload = {'credentials': $scope.logindata};
    REST.load('access', 'login', payload).success(function(data) {
        if(data.redirect)
            $state.go(data.redirect);
        $scope.loading = false;
    }).error(function(data) { //THIS SHOULD BE CALLED
        $scope.loading = false;
    });
}

2 回答

  • 1

    首先,我强烈反对你将 .success 附加到你要归还的承诺上 . 这不是Promises / A兼容,它与 .then 的细微差别(由 $http 实现)会引起很多混乱 . 回报一个纯粹的承诺 .

    除此之外,还有几点需要注意:

    1) 你不需要另一个 $q.deferdeferred.resolve() - 只是链接到 $httpreturn 的原始承诺 . (见deferred anti-pattern

    2) 拒绝承诺 - 也就是说,要使 .catch (不是 .error - 参见上面关于细微差别的内容)来解雇 - 你应该返回 $q.reject() .

    以上所有产生以下内容:

    app.factory('REST', function($http, $q, sweetAlert){
      return {
        load: function(module, action, data) {
          // this "return" returns the promise of $http.then
          return $http.post('/api/' + module + '.php?action=' + action, data)
            .then(function(response) {
              var data = response.data; // .then gets a response, unlike $http.success
    
              if (data.error) {
                sweetAlert.swal({
                  title: "Error",
                  text: data.error,
                  type: "warning"
                });
    
                //HERE I WANT TO CALL .error(details)
    
                return $q.reject(data.error);
              }
    
              return data.result; // what you would have "resolved"
            });
        }
      };
    })
    

    然后,正如我上面所说,使用 .then / .catch ,就像你对promises一样:

    $scope.login = function () {
        $scope.loading = true;
        var payload = {'credentials': $scope.logindata};
        REST.load('access', 'login', payload)
            .then(function(data) {
              if(data.redirect)
                 $state.go(data.redirect);
              $scope.loading = false;
            })
            .catch(function(error) {
              $scope.loading = false;
            });
    }
    
  • 4

    更新以下代码

    app.factory('REST', function ($http, $q, sweetAlert) {
       return {
           load: function (module, action, data) {
                  var deferred = $q.defer();                  
                      $http.post('/api/'+module+'.php?action='+action, data)
                              .success(function (data) {
                                  if(data.error)
                                  {
                                      sweetAlert.swal({
                                          title: "Error",
                                          text: data.error,
                                          type: "warning"
                                      });     
                                     //HERE I WANT TO CALL .error(details)                                
                                     deferred.reject(data.error);
                                  }
                                  else{
                                    deferred.resolve(data.result);
                                  }
    
                             })
                             .error(function (error) {
                                  //HERE I WANT TO CALL .error(details)
                                  deferred.reject(error);   
                              });
    
                   return defferred.promise;
              }
       };
    });
    

    对于你的控制器

    $scope.login = function () {
         $scope.loading = true;
         var payload = {'credentials': $scope.logindata};
         REST.load('access', 'login', payload).then(
           function(data) {
             if(data.redirect)
                 $state.go(data.redirect);
                 $scope.loading = false;
           },
           function(error) {
              $scope.loading = false;
           });
       }
    

相关问题