Angular promise返回404,最终不会触发

时间:2016-07-28 15:37:32

标签: angularjs promise

我是否误解了承诺并最终?

我发布的是尚未构建的API。它返回404 - 正如我所期望的那样 - 但控制器函数AdminManifestService.postManifest永远不会完成,所以我有一个微调器(绑定到vm.processingButton)永远。

一旦获得404,它是否应该立即返回失败的承诺?

控制器:

    vm.sendManifest = function () {
        vm.processingButton = true;
        var manifest = vm._buildManifest();
        AdminManifestService.postManifest(manifest)
            .then (
                function success(response) {
                    toastr.success("Manifest has been sent.");
                },
                function fail(response) {
                    toastr.error(response.data);
                }
            )
            .finally(function(){
                vm.processingButton = false;
            }
        );
    }

服务:

function adminManifestService($http, $q, ngAuthSettings) {

    var dataSource = 'api';

    // GET User Markups
    var _postManifest = function (data) {

        return $q (function(resolve, reject) {
            switch (dataSource) {
                case 'api': //staging - live api data
                    return $http({
                        method: 'post',
                        url: serviceBase + 'api/Admin/Manifest/',
                        data: data
                    }).then(function(results) {
                         resolve(results.data);
                    });
                    break;
                default: // dev - local json
                    resolve();
            }
        });
    };

    adminManifestService.postManifest = _postManifest;

    return adminManifestService;
}

2 个答案:

答案 0 :(得分:2)

您永远不会拒绝adminManifestService中的承诺,因此会吞下$http拒绝。

小心!您是promise anti-pattern的受害者。

不要将$http承诺与$q包装在一起,只需将其退回:

var _postManifest = function (data) {
  if (dataSource !== 'api') {
    return $q.resolve();
  }

  return $http({
    method: 'post',
    url: serviceBase + 'api/Admin/Manifest/',
    data: data
  }).then(function(results) {
    return results.data;
  });
};

您也可以在此处添加errorCallback

var _postManifest = function (data) {
  if (dataSource !== 'api') {
    return $q.resolve();
  }

  return $http({
    method: 'post',
    url: serviceBase + 'api/Admin/Manifest/',
    data: data
  }).then(function(results) {
    return results.data;
  }, function(results) {
    // Note that we need to return a rejected promise
    return $q.reject(results.data);
  });
};

这样您就可以用最少的工作来使用您的服务:

adminManifestService.postManifest(manifest)
  .then(function() {
    toastr.success("Manifest has been sent.");
  }, toastr.error)      // You can just send `toastr.error` here
  .finally(function(){
    vm.processingButton = false;
  });

答案 1 :(得分:0)

$http服务返回promise本身,这意味着无需在$q中包装任何内容。这里有Plunker简化的概念验证。

function adminManifestService($http, $q, ngAuthSettings) {

    var dataSource = 'api';

    // GET User Markups
    var _postManifest = function (data) {

        switch (dataSource) {
            case 'api': //staging - live api data
                return $http({
                    method: 'post',
                    url: serviceBase + 'api/Admin/Manifest/',
                    data: data
                })
                break;
            default: // dev - local json
                return new Promise(function(resolve){
                    resolve({data:"dev data"})
                })
        }
    };

    adminManifestService.postManifest = _postManifest;

    return adminManifestService;
}

控制器

vm.sendManifest = function () {
    vm.processingButton = true;
    var manifest = vm._buildManifest();
    AdminManifestService.postManifest(manifest)
        .then (
            function success(response) {
                toastr.success("Manifest has been sent.");
                vm.processingButton = false;
            }
        )
        .catch(function(err){
              toastr.error(err);
              vm.processingButton = false;
        });
}