2017-08-04 14 views
0

I HTMLにng-clickから実行されます、次の機能があります。実行するコマンドがで終了角度

vm.items = []; 
vm.moveItems = function() { 
    angular.forEach(vm.items, 
     function (item) { 
      $http({ 
       method: 'PUT', 
       url: '/api/item_move/' + item.id} 
      }).then(function(response) { 
       Toast.success("Successfully moved item " + item.id); 
       vm.reload(); 
      }, function (error) { 
       Toast.error("Failed to move item " + item.id, error); 
      }); 
    }); 
}; 

さて、問題はvm.reload()が成功するたびに応答した後に実行されるということですがどこ実際にはそれforEachが終了した後に1回実行されたとすれば十分でしょう。私はJSの非同期プログラミングにはとても新しいので、これを解決するために最もよく使われている方法を知りたいと思っています。 foreachループの外

答えて

2

はあなたのHTTP呼び出しから約束を保存する配列を作成します。その後Promise.all()メソッドに呼び出します。これは、すべての約束が終わったときに、あなたが何かをすることを可能にします。

vm.items = []; 
vm.moveItems = function() { 
    var promises = []; 
    angular.forEach(vm.items, 
     function (item) { 
      promises.push($http({ 
       method: 'PUT', 
       url: '/api/item_move/' + item.id} 
      })); 
    }); 
    Promise.all(promises) 
     .then(function() { 
      vm.reload(); 
     }); 
}; 

編集:あなたはAngularJSを使用しているので、あなたも$q.all()を行うことができます。

+0

パーフェクト!私はこれが一般的なJSソリューションだと考えています。 Angularにはこのための '$ q'コンストラクタがあります。単純なJSソリューションを使用する方が良いでしょうか? – mart1n

+0

@ mart1nはい、ES6で追加されたJSソリューションです。 '$ q'でも可能です(https://docs.angularjs.org/api/ng/service/$qを参照)。' $ q'を使う方が良いでしょう。 –

+0

's/Promise/$ q /'は唯一の変更ですか? – mart1n

-1

移動vm.reload():

vm.items = []; 
vm.moveItems = function() { 
    this._$timeout(() => { 

    angular.forEach(vm.items, 
     function (item) { 
     $http({ 
      method: 'PUT', 
      url: '/api/item_move/' + item.id} 
     }).then(function(response) { 
      Toast.success("Successfully moved item " + item.id); 
     }, function (error) { 
      Toast.error("Failed to move item " + item.id, error); 
     }); 
    }); 

    }); 

    vm.reload(); 
}; 

編集は、$タイムアウトを追加し、それをforeachループを終了するのに十分な時間を与える必要があります。

+0

私は、この作品とは思わない、それはありませんか? forEachのリクエストは起動し、リクエストは実際に終了する前にリロードされます。 – mart1n

+0

HTTPコールに時間がかかるため、これは機能しません。 vm.reload()は、要求が完了する前に呼び出されます。 –

+0

$ timeoutコールを追加するように編集しました.HTTPコールが終了するようにしてください。 – rrd

0

あなたはこのような何かを行うことができます:

vm.items = []; 
vm.moveItems = function() { 
var i = 0 
    angular.forEach(vm.items, 
     function (item) { 
      $http({ 
       method: 'PUT', 
       url: '/api/item_move/' + item.id} 
      }).then(function(response) { 
       Toast.success("Successfully moved item " + item.id); 
       i++; 
       if(i == vm.items.length{ // execute only when its the last loop of foreach 
        vm.reload(); 
       } 

      }, function (error) { 
       i++; 
       if(i == vm.items.length{ // execute only when its the last loop of foreach 
        vm.reload(); 
       } 
       Toast.error("Failed to move item " + item.id, error); 
      }); 
    }); 
}; 
+0

それは動作しますが、それは悪いコーディングスタイルです。 –

+0

@ D.Simonあなたは正しいです。あなたの答えはより良いです。 –

0

ソリューション:

vm.items = []; 

vm.moveItems = function() { 
    var promises = []; 

    angular.forEach(vm.items , function(item) { 

     var promise = $http({ 
      method: 'PUT', 
      url: '/api/item_move/' + item.id} 
     }).then(function(response) { 
      Toast.success("Successfully moved item " + item.id); 
     }, function (error) { 
      Toast.error("Failed to move item " + item.id, error); 
     }); 

     promises.push(promise); 

    }); 

    $q.all(promises).then(function() { vm.reload() }) 
}); 
関連する問題