【问题标题】:How do I know with Angular and $q.all which requests succeeded and which failed我如何使用 Angular 和 $q.all 知道哪些请求成功,哪些失败
【发布时间】:2016-11-27 06:37:03
【问题描述】:

我有一个表格,用户可以在其中选择多行并点击删除按钮。我需要我的代码循环遍历选定的记录并删除它们。

我正在调用customerService.delete({id: id}) 删除每条记录,但是我需要知道哪个失败,哪个成功,以便我可以适当地处理它。

我尝试过使用$q.all,但我不确定如何知道哪些行失败,哪些行成功:

var promises = [];
$('input:checkbox:checked', $('#customers')).each(function() {
    var nRow = $(this).closest('tr')[0];
    var aData = oTable.fnGetData(nRow);
    var id = aData[0];      
    promises[id] = customerService.delete({id: id}).$promise;
});
$q.all(promises).then(
    function(data) {
        console.log(data);         
    }, function(data) {
        console.log(data);
    }
);

我如何知道我的哪些删除操作失败和成功?

编辑:我已经尝试了以下方法,但对于 idstatus 却未定义。

      var promises = [];
      $('input:checkbox:checked', $('#customers')).each(function() {
          var nRow = $(this).closest('tr')[0];
          var aData = oTable.fnGetData(nRow);
          var id = aData[0];
          var promise = customerService.delete({id: id}).$promise;
          promise.then(function(){
              return {status: true, id: id}
          }).catch(function(){
              return {status: false, id: id}
          })    
          promises.push(promise); 
      });

      $q.all(promises).then(function(results) {
         $.each(results, function(result) {
           console.log(result.id + ' ' + result.status);
         });
      });

results 看起来像:

【问题讨论】:

    标签: jquery angularjs promise deferred


    【解决方案1】:

    当你返回到一个 Promise 的 catch() 内时,它也会沿着链传递一个已解决的 Promise

    $('input:checkbox:checked', $('#customers')).each(function() {
        var nRow = $(this).closest('tr')[0];
        var aData = oTable.fnGetData(nRow);
        var id = aData[0];
        var promise =   customerService.delete({id: id}).$promise;
        promise.then(function(){
            return {status: true, id: id}
        }).catch(function(){
            return {status: false, id: id}
        })    
        promises.push(promise); 
    });
    
    $q.all(promises).then(function(results) {
       var failedDeletes = results.filter(function(item){
           return !item.status;
       });
    });
    

    【讨论】:

    • catch返回以兑现承诺+1,太棒了:)
    • 感谢您的回复。看我的更新。我没有看到 statusid reurned。
    • 那么results 是什么样的?
    • 查看我的编辑。它是一个数组(正如预期的那样) - 我已经展示了数组的第一个键。我在返回的对象上没有看到 statusid
    • 因此我将.then 更改为在运行时仅显示警报,并且仅在删除操作成功时才​​运行。我将后端代码更改为抛出 404,当它这样做时,我在 $.all 上的 .then 函数中放置的警报不会被触发。
    【解决方案2】:

    您尝试做的问题是 $q.all 只给出第一个被拒绝的值。来自docs

    如果任何一个 Promise 被拒绝解决,这会导致 Promise 会以相同的拒绝值被拒绝。

    您可以在下面的示例中看到这种情况,即使它也被拒绝,也没有返回“test3”。

    (function() {
      angular
        .module('exampleApp', [])
        .controller('ExampleController', ExampleController);
    
      function ExampleController($q) {
        var vm = this;
        var passedResults = [];
        var rejectedResults = [];
    
        function pushPassedResults(result) {
          passedResults.push(result);
        }
    
        function pushRejectedResults(result) {
          rejectedResults.push(result);
        }
        $q.all($q.reject('test1'), $q.reject('test3'),
            $q.when('test2'))
          .then(
        function(data) {
            console.log(data);         
        }, function(data) {
            console.log(data);
        });
      }
      ExampleController.$inject = ['$q'];
    })();
    <!DOCTYPE html>
    <html ng-app='exampleApp'>
    
    <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
    </head>
    
    <body ng-controller="ExampleController as vm">
    </body>
    
    </html>

    为了得到结果,我们需要在 $q.all 完成对 promise 的解析之前得到它。示例如下:

    (function() {
      angular
        .module('exampleApp', [])
        .controller('ExampleController', ExampleController);
    
      function ExampleController($q) {
        var vm = this;
        var passedResults = [];
        var rejectedResults = [];
    
        function pushPassedResults(result) {
          passedResults.push(result);
        }
    
        function pushRejectedResults(result) {
          rejectedResults.push(result);
        }
        $q.all($q.reject('test1').then(pushPassedResults).catch(pushRejectedResults), 
               $q.reject('test3').then(pushPassedResults).catch(pushRejectedResults),
            $q.when('test2').then(pushPassedResults).catch(pushRejectedResults))
          .finally(function() {
            console.log("Passed results:" + passedResults);
            console.log("Rejected results:" + rejectedResults);
          });
      }
      ExampleController.$inject = ['$q'];
    })();
    <!DOCTYPE html>
    <html ng-app='exampleApp'>
    
    <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
    </head>
    
    <body ng-controller="ExampleController as vm">
    </body>
    
    </html>

    【讨论】:

      【解决方案3】:

      $q.all 接受承诺数组。目前,您正在创建基于 index 的数组推送,这不会做任何事情(它将在 JSON/Object 上工作)。理想情况下,您应该通过 promises.push 将 promise 推送到数组中,如下所示。

      promises.push(customerService.delete({id: id}).$promise);
      

      【讨论】:

      • 为什么按索引向数组添加promise会出现问题?为什么需要推送?
      猜你喜欢
      • 2021-06-10
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      • 2019-07-25
      相关资源
      最近更新 更多