2016-03-31 9 views
0

私は約束の初心者です。私はちょうど、同意を同期的に解決する方法を知りたがっていました。たとえば、解決HTTPの同意を同意して

var app = angular.module("app", []); 

app.service("githubService", function($http, $q) { 

    var deferred = $q.defer(); 

    this.getAccount = function() { 
    console.log(2) 
    return $http.get('https://api.github.com/users/haroldrv') 
     .then(function(response) { 
     // promise is fulfilled 
     deferred.resolve(response.data); 
     return deferred.promise; 
     }, function(response) { 
     // the following line rejects the promise 
     deferred.reject(response); 
     return deferred.promise; 
     }); 
    }; 
}); 

app.controller("promiseController", function($scope, $q, githubService) { 
    console.log(1) 
    githubService.getAccount() 
    .then(
     function(result) { 
     console.log(3) 
     // promise was fullfilled (regardless of outcome) 
     // checks for information will be peformed here 
     $scope.account = result; 
     }, 
     function(error) { 
     console.log(3) 
     // handle errors here 
     console.log(error.statusText); 
     } 
    ); 
    console.log(4) 
}); 

上記のコードでは、値は1,2,4,3の順番で印刷されます。つまり、サービスが呼び出され、応答が同期的に取得されます。しかし、それが受け取ったhttp約束を解決する前に、次の行に到達します。私は応答の中で別の遅延を使ってみましたが、うまくいきません。だから、 '3'の後に '4'に達する方法は?ここにプランカーリンクがあります。http://plnkr.co/edit/AI8OJAgqFDVXb1fRYbix?p=preview

これについての助けがあれば幸いです。

+1

まず、[繰延アンチパターンを](http://stackoverflow.com/q/23803743/1048572)(またはDeferredの作り方の使用のこの種があるものは何でも避けることができます確かにこれは意図したとおりに動作し、実際にその動作を意図していた場合は、キャッシングの方がはるかに優れた単純なソリューションがあります)。 – Bergi

+0

'console.log(4)'を別の 'then'セクションにラップします... –

答えて

3

これは非同期呼び出しの性質です。コール終了後に実行するコードは、コールバック内に配置する必要があります。 4番目のログ文は、非同期呼び出しをスキップして、すぐに実行されます。

ヒント:遅延オブジェクトを作成することは、常にコードの匂いです。実際に必要としない時間の99%です。たとえば、あなたがこのようなあなたのサービスコードを書くことができ、それはまったく同じことを行いますが、あなたのコードは、はるかに短いです:

app.service("githubService", function($http, $q) { 

    this.getAccount = function() { 
    console.log(2) 
    return $http.get('https://api.github.com/users/haroldrv') 
     .then(function(response) { 
     return response.data; 
     }); 
    }; 
}); 

約束の本当に優秀な説明については、ノーランローソンでthisブログ記事を確認してください。あなたのplunkerで

0
  • あなたが$http呼び出しを返す場合は、それがコントローラに約束を返却するサービスで.then()を呼び出すために を持っていません。
  • ここで応答を処理する場合は、.success().error()コールバックを使用する必要があります。 JavaScriptが非同期 あるので
  • は今それがgithubService.getAccount()と 後に定義されているので、それは が実行されることはありません飽きないだろう、その位置であなたのconsole.log(4)に来ては、その直後にこの方法を実行されます。 githubService.getAccount()はそのコールバックを として登録するだけです。

javacript/angularの約束を理解するためにplunkerを作成しました。私はない -

希望は、これはすべての

関連する問題