2017-01-24 6 views
2

次のパターンのコードがあります。このコードでは、ユーザーがビューのデータを更新するたびに更新が呼び出されます。約束が返る前にpromiseの2回目の呼び出しが実行されます - 角型JavaScript

// FACTORY SERVICE CODE 
.factory('updateService', ['$http', '$q', function($http, $q){ 
    var df = $q.defer(); 
    var updateData = function(uriName, dataObj){ 
     $http({ 
      method: 'PUT', 
      data: dataObj, 
      url: uriName 
      }).then(function successCallback(response) { 
       console.log('from put'); 
       console.log(response.data); 
       df.resolve(response.data); 
      }, function errorCallback(response) { 
       console.log('Error', response.data); 
       df.reject(response.data); 
     }); 
     return df.promise; 
    } 
    return {updateData:updateData}; 
}]) 

// CONTROLLER CODE 
.controller('MainCtrl', ['$scope','updateService', function($scope, updateService) { 
    $scope.saveToServer = function(){ 
     var tmpObj = {data: $scope.dataOne, anotherData: $scope.dataTwo}; 
     myService.updateData(uriName, tmpObj).then(function(resolved) { 
      console.log('CONTROLLER'); 
      $scope.myData = resolved; 
      console.log($scope.myData); 
      console.log('end'); 
     }, function(rejected){ 
      console.log('put rejected'); 
     }); 
    }); 
    $scope.btnUpdateClick = function(){ 
     $scope.saveToServer(); 
    }; 
}]); 

問題:ユーザが最初の更新要求を行うと予想されるように、コードは 働きます。しかし、ユーザーがその後に更新すると、「解決済みの約束」コード(コントローラ内)がFIRSTを実行し、$ httpコード(サービス内)が実行されます。

from put 
Array [ Object, Object] 
CONTROLLER 
Array [ Object, Object] 
end 
CONTROLLER 
Array [ Object, Object] 
end 
from put 
Array [ Object, Object] 

QUESTION:私は間違いを犯してよどこ は親切に私を指摘btnUpdateClickの

サンプル出力は、イン間に十分な間隔で二回作ったのですか?

PUTリクエストのために問題がありますか?

または実行キューを$ applyなどで期待通りに修正することは可能ですか?

+0

'VAR DF = $ Q。defer(); 'このコードを' updateData'関数の中に入れてください。 そして別の提案は、$ http呼び出しのための別の約束事を作成する理由です。 $ http約束を返すだけです。 –

+0

@pragaas upvoting後に回答を受け入れる方が良いでしょう:) –

+0

@ARUN - 正しく指摘されています。 – Mikki

答えて

1
約束あなたが以下のような関数を呼び出すたびに起動し

.factory('updateService', ['$http', '$q', function($http, $q){ 

    var updateData = function(uriName, dataObj){ 
     var df = $q.defer(); //Changes here 
     $http({ 
      method: 'PUT', 
      data: dataObj, 
      url: uriName 
      }).then(function successCallback(response) { 
       console.log('from put'); 
       console.log(response.data); 
       df.resolve(response.data); 
      }, function errorCallback(response) { 
       console.log('Error', response.data); 
       df.reject(response.data); 
     }); 
     return df.promise; 
    } 
    return {updateData:updateData}; 
}]) 

あなたはすべての関数呼び出しに新しい約束を作成している。このように。

0
にコードを変更し

:あなたはそれが一度だけ拒否/解決したように、一度だけオブジェクトを延期作成していた古いコードで

// FACTORY SERVICE CODE 
.factory('updateService', ['$http', '$q', function($http, $q){ 
    var updateData = function(uriName, dataObj){ 
     var df = $q.defer(); 
     $http({ 
      method: 'PUT', 
      data: dataObj, 
      url: uriName 
      }).then(function successCallback(response) { 
       console.log('from put'); 
       console.log(response.data); 
       df.resolve(response.data); 
      }, function errorCallback(response) { 
       console.log('Error', response.data); 
       df.reject(response.data); 
     }); 
     return df.promise; 
    } 
    return {updateData:updateData}; 
}]) 

// CONTROLLER CODE 
.controller('MainCtrl', ['$scope','updateService', function($scope, updateService) { 
    $scope.saveToServer = function(){ 
     var tmpObj = {data: $scope.dataOne, anotherData: $scope.dataTwo}; 
     myService.updateData(uriName, tmpObj).then(function(resolved) { 
      console.log('CONTROLLER'); 
      $scope.myData = resolved; 
      console.log($scope.myData); 
      console.log('end'); 
     }, function(rejected){ 
      console.log('put rejected'); 
     }); 
    }); 
    $scope.btnUpdateClick = function(){ 
     $scope.saveToServer(); 
    }; 
}]); 

。しかし、あなたが必要とするのは毎回約束を返し、毎回それを解決/拒否することです。

+0

"あなたのコードを変更する" - なぜですか?何が間違っていた? –

+3

コードのみの回答はそれほど有用ではありません。それを修正する必要があることを説明してください。 – Pointy

+0

忍耐力を持っている@Pointy –

3

悪い習慣とみなされていますが、ここにカスタムプロミスを作成する必要はありません。

PUTリクエストのために問題がありますか?

PUTリクエストに関連する問題ではありません。あなたの工場が共通のdeferredオブジェクトを使用していて、同じものがメソッドから返されました。そのpromiseオブジェクトが解決されると、常に解決状態になります。


むしろ私はあなたが$http.put約束を利用することをお勧めし、あなたが前に持っていたものよりも、あなたのコードを小さくしたいと思います。

var updateData = function(uriName, dataObj){ 
    return $http.put(uriName,dataObj) 
} 
+0

コーディングのあなたのアプローチは絶対に正しいです。しかし、私の質問は私が自分のコードで持っていた間違いの修正に関するものだったので、もう一つの答えを記録に残しておきたいと思います。 良い仕事! – Mikki

4

あなたはここに"explicit promise creation antipattern"を使用して、そしてその上に、すべてのサービスコールの中で、1つの遅延オブジェクトを共有しようとしています。

だけ延期を取り除くと約束連鎖する特性を利用し、すべてが良いだろう取得:

.factory('updateService', ['$http', '$q', function($http, $q){ 
    var updateData = function(uriName, dataObj){ 
     return $http({ 
      method: 'PUT', 
      data: dataObj, 
      url: uriName 
     }) 
     .then(function successCallback(response) { 
      console.log('from put'); 
      console.log(response.data); 
      return response.data; 
     }) 
     .catch(function errorCallback(response) { 
      console.log('Error', response.data); 
      throw response.data; 
     }); 
    }; 

    return {updateData:updateData}; 
}]); 
+0

あなたのコーディング方法は絶対に正しいです。しかし、私の質問は私のコードにあった間違いの修正に関するものだったので、私はその解決策を答えとして記録したいと思っています。 良い仕事! – Mikki

+0

とても、絶対に –

関連する問題