2017-01-13 10 views
0

のサイクルは、私はこのように、のために関数を呼び出すときに、この機能のすべてのi番目の応答が返されます。私はのためにJavaScript関数を呼び出すと、最後

for(var i=0; i<$scope.staffdispensers.length; i++){  
         console.log($scope.staffdispensers[i].dispenser.iddispenser); 
         restService.Enforsaleproductsbyiddispenser($scope.staffdispensers[i].dispenser.iddispenser, _getnumber, _error); 
       } 

はこれがありますこの関数の実装は:

Enforsaleproductsbyiddispenser: function(id, _getnumber, _error){ 
     var currentToken = _GetToken(); 

     _timerTokenControl(currentToken, _error); 

     if (setupTime == null) { 
      console.log("token scaduto"); 
      $window.location.href="login.html"; 
     } 


     if (currentToken !== null) { 
     $http({ 
        method : 'GET', 
        url : REST_URL+'products/nforsalebyiddisp/'+id 
       }).then(function successCallback(response) { 
        _getnumber(response); 
       }, function errorCallback(response) { 
        console.log(response.statusText); 
       }); 
      } else { 
       $window.location.href="login.html"; 
       console.log("NON SEI LOGGATO!!!"); 
     } 
    } 

これを見てください。 "_getnumber(応答);"すべてのforループを終了した後に呼び出されます。 これは_getnumber機能である:私は

コンソールを見ると
function _getnumber(response){ 
       number.push(response.data); 
       console.log(number); 

} 

は、番号配列で、私はそれぞれの機能のすべての結果を持っている:

enter image description here

しかし、私はリフレッシュしようとした場合ページ、私は同じ値を持っているが、別の順序である!

enter image description here

そして、これがために起こる "_getnumber(レスポンス);"すべてのforループを終了した後に呼び出されます。それを見て:

enter image description here

は、私は、iでステップバイステップを_getnumber呼び出したい私のメインemployee.jsで

:残り-services.jsで

enter image description here

enter image description here

+0

結果の順序に問題はありますか?もしそうなら、あなたは約束のために非同期を使うかもしれません。 – briosheje

+0

問題は順序です!私はこれらの値を順番に欲しいですが、この場合の順序はランダムです –

+0

これは、http要求が非同期であるためです。主に問題を解決するには2つの方法があります:1)索引付きの通常のループ。 2)約束のある非同期ループ。レキシカルスコープの男。 – briosheje

答えて

1

$ httpでajaxCallを実行しています。この特定の$ http呼び出しは非同期で、どれくらい時間がかかるかは保証されていません。

通話が正常に終了したときに_getNumberを呼び出しています。複数の通話が途切れている場合、最初の通話は最後の通話の後に完了することができます。

したがって、保証された注文はありません。

リターンの約束:

if (currentToken !== null) { 
      return $http({ 
        method : 'GET', 
        url : REST_URL+'products/nforsalebyiddisp/'+id 
       }).then(function successCallback(response) { 
        _getnumber(response); 
       }, function errorCallback(response) { 
        console.log(response.statusText); 
       }); 
     } else { 
       $window.location.href="login.html"; 
       console.log("NON SEI LOGGATO!!!"); 

       var def = $q.deferred(); 
       def.resolve(); 
       return def.promise; 
     } 

約束が解決されたときに

function recursiveCall(i) { 
      if (i < $scope.staffdispensers.length) { 
       console.log($scope.staffdispensers[i].dispenser.iddispenser); 
restService.Enforsaleproductsbyiddispenser($scope.staffdispensers[i].dispenser.iddispenser, _getnumber, _error) 
       .then(function(){ 
        recursiveCall(i+1) 
       }) 
      } 
     } 

はあなたが呼んでいる初期再帰呼び出し

recursiveCall(0); 
+0

の中で '未定義のプロパティ'を読み取れません)私の場合はどうすれば解決できますか? –

+0

あなたは関数を返す必要があります。約束が解決されたときに他の呼び出しを実行するには、更新された答えを確認してください –

+0

アイデアはありますか?再帰呼び出しの前に例で使用したコンソールログの順序を保証するために呼び出しを同期する必要があります。それだけで成功を呼び出す... –

0

を呼び出して自分自身を呼び出す再帰関数を書きます非同期関数は、すべてのrespを取得する前にforループが完了する可能性が高いことを意味しますonses。順序は、各非同期呼び出しがいつ完了するかによって異なります。データを順番に取得する必要がある場合は、応答を順序付けるためのメカニズムを実装するか、呼び出しが完了するまで待つ必要があります。これを行う1つの方法は、すべてのサーバー呼び出しが行われるまで成功コールバックで再度フェッチを呼び出すことです。

+0

そしてどうすればいいですか? –

+0

約束なしでそれを行う簡単な方法d waitingは、非同期呼び出しの応答が対応するインデックスを渡すことです。長さ '$ scope.staffdispensers.length'の配列を初期化し、' arr [i] = response.data'を設定します。欠点は、すべての非同期呼び出しが完了した時点を知らないことです。 –

0

ああはい。あなたは、$http呼び出しが同じ順序で返ってくることは確実ではありません。応答が遅い場合もありますが、速い場合もあります。注文を実施する唯一の方法は、約束を賢明に使用することです。 ...

結果の順序を強制するために、約束である$http呼び出しの戻り値を使用する必要があります。

var promises = []; // this will hold promises in correct order 
for(var i=0; i<$scope.staffdispensers.length; i++){  
    console.log($scope.staffdispensers[i].dispenser.iddispenser); 
    var promise = restService.Enforsaleproductsbyiddispenser($scope.staffdispensers[i].dispenser.iddispenser, _getnumber, _error); 
    promises.push(promise); 
} 

すべての約束を$qプロバイダ使用して終了するまで今、あなたは待つことができます:

$q.all(promises).then(function(arrayOfPromises) { //array is of all resolved promises 
    angular.forEach(arrayOfPromises, function(promise) { 
    promise.then(function(response) { 
     _getnumber(response); 
    }) 
    .catch(function(error) { 
    }); 
    }); 
}); 

をそれだけで$http応答を返すようにあなたは、あなたの$httpの呼び出しを変更する必要があります

return $http({ 
     method : 'GET', 
     url : REST_URL+'products/nforsalebyiddisp/'+id 
     }); 
関連する問題