2016-12-21 8 views
1

forループ内で私は連続して約束をします、私はこれを行うにはGoogleでたくさんの例を見ましたが、私のケースでは実装できませんでした: 私はこれを通りましたlink約束の連鎖。AngularJSチェーンはForループ内で連続して約束します

私が習得しようとしているもの:
Promise1:login();
Promise2:sync();

sync関数は、要素の配列に対して別のサービスcomplete()を呼び出します。これらの要素の配列は、順次実行する必要があります。

ServiceA.login(). 
     then(function(response){ 
        ServiceA.sync() 
         .then(function(response){ 

         }) 
     }) 

function sync(){ 
    ServiceB.complete() 
        .then(function(){ 
           var promises = []; 
           angular.forEach(response, function (value) { 
        // The below service call doSomething() must be done sequentially for each "value" 
            promises.push(doSomething(value)); 
           }); 
           $q.all(promises).then(function() { 


             }); 
            }); 

         }) 
} 

各プロミスで発生したエラーをどのようにキャプチャしますか?

更新:各ループの近くで応答が持っている場合

ServiceA.login() 
.then(function(response){ 
    // you must always return your promise 
    return ServiceA.sync() 

}) 
// don't nest the .then make them flat like this 
.then(function(response){ 

}) 
.catch(function(){ 
    // if you made sure to always return your promises this catch will catch any errors throws in your promise chain including errors thrown by doSomething() 
}); 

function sync(){ 
// you must always return your promise 
return ServiceB.complete() 
    .then(function(){ 

     var result = $q.when(); 
     angular.forEach(response, function (value) { 
      result = result.then(doSomething(value)); // problem is here that doSomething function is being called before the first call it is resolved 
// doSomething is a http call. 
     }); 
     return result; 
    }) 
    .then(function(){ 
     // the array of promises has run sequentially and is completed 
    }); 

}

function doSomething(data){ 
     return $http({ 
      method: 'POST', 
      url: '/api/do', 
      data: data, 
      headers: { 
       "Content-Type": "application/json" 
      } 
     }).then(function (response) { 

     }, function (error) { 

     }); 
    } 

:私は次のコードで@zaptreeによってアプローチを試みを示唆している
2の値(valuea、valueb)を使用すると、コードは次のように動作します。
1.呼び出しdoSomething(valuea)
2.上記の約束が解決される前にdoSomething(valueb)を呼び出します。
期待される振る舞い:doSOmething(valuea)の呼び出しによってPOSTメソッドが正常に完了した後、別のPOST呼び出しが起こるはずです(soSomething(valueb))。

+0

なぜ連続していますか?彼らはお互いに依存していますか? –

+0

はいこれらは互いに依存します – CodingFreak

+1

'$ q.all([...])'はいずれか一方が失敗しても並列に実行されないと失敗します。シーケンシャルに実行するには '.then()'で連鎖する必要があります。 –

答えて

2

ここで私が思いついたのです。配列を単一の約束に減らす必要があります。

var results = [...]; 
var sequentialPromise = results.reduce(function(a, b) { 
    return a.then(function(){ 
    return doSomething(b); 
    }); 
}, $q.resolve()); 

sequentialPromise.then(function(){...}); 
+0

あなたはそれを構築しているので、約束のチェーン上の 'doSomething()'はしませんか? – chester

+0

最初のものがあります。コールバックがIEと呼ばれるときにのみ他のものが発生します - 前の約束は終わりです。 –

+2

たぶん私は何かを見逃しているかもしれませんが、 'reduce'の最初のループの間に' a'は約束していませんか? a.then(function(){return doSomething(b)}); 'を返す必要があるのを' reduce'しません。 – chester

0

は、だからここにあなたがQとシーケンシャル約束、あなたが適切にあなたの約束チェーンの任意の時点でスローされたエラーをキャッチすることができますので、あなたの約束を行う方法についてもいくつかの改善を行うだろう方法の例です。あなたは常にそれを使用するどのような方法でも約束を返さなければなりません。また、コードをきれいにするために.thenを入れ子にしないでピラミッドコードを避けてください:

ServiceA.login() 
    .then(function(response){ 
     // you must always return your promise 
     return ServiceA.sync() 

    }) 
    // don't nest the .then make them flat like this 
    .then(function(response){ 

    }) 
    .catch(function(){ 
     // if you made sure to always return your promises this catch will catch any errors throws in your promise chain including errors thrown by doSomething() 
    }); 

function sync(){ 
    // you must always return your promise 
    return ServiceB.complete() 
     .then(function(){ 

      var result = $q.when(); 
      angular.forEach(response, function (value) { 
       result = result.then(doSomething(value)); 
      }); 
      return result; 
     }) 
     .then(function(){ 
      // the array of promises has run sequentially and is completed 
     }); 

} 
+0

これはサービスでも機能しますか?またはそれは工場とサービスの両方で機能しますか? – CodingFreak

+0

これは '.then()'でコールバック関数を指定する必要があります –

+0

'var result = $ q();の近くにエラーが表示されます' 'ServiceB.inject = '$ q'] '。 – CodingFreak

関連する問題