2016-05-04 22 views
3

移動する前に一時停止して$ http応答を待つコードがないようです。現在、私のコードは次のようなものになります。

var postAuthorCache = new Array(); 
angular.forEach($scope.news.posts, function(value, key) { 
    console.log(JSON.stringify(postAuthorCache)); //Keeps printing "[]" 
    if (!(value["post_author"] in postAuthorCache)) { 
     $http.get('/api/tumblr_primaryblog_name/' + value["post_author"]).then(function(response) { 
      postAuthorCache[value["post_author"]] = response.data; 
      value["post_author_pblog"] = postAuthorCache[value["post_author"]]; 
      console.log("NOT CACHE: " + value["post_author"]); 
     }); 
    } else { 
     value["post_author_pblog"] = postAuthorCache[value["post_author"]]; 
     console.log("IN CACHE: " + value["post_author"]); 
    }; 
}); 

をしかし、それが実行したときに、出力にconsole.logは私が予想していたものではありません。

[] 
[] 
[] 
[] 
[] 
[] 
[] 
NOT CACHE: aaaa 
NOT CACHE: bbbb 
NOT CACHE: aaaa 
NOT CACHE: aaaa 
NOT CACHE: aaaa 
NOT CACHE: aaaa 
NOT CACHE: bbbb 

私は期待していた出力が最初に実行されるようにconsole.log(JSON.stringify(postAuthorCache));を持っているし、$はhttpを照会した後、それはconsole.log("NOT CACHE: " + value["post_author"]);またはconsole.log("IN CACHE: " + value["post_author"]);のいずれかを実行します。その後、配列オブジェクトのstringifyを再度表示して、それ自身を繰り返す必要があります。NOT CACHEまたはIN CACHEログステートメントを実行してください。

それでは、移動する前に、$ http.getが完了するのをforeachループがどのように待つのでしょうか?

+0

これを達成するための複数の方法がありますが、実際にどのように値を使用するのかを理解するためには、 'console.log'メッセージの順序は使い方が似ていない可能性が高いからです。そうであれば、 'forEach'を使う代わりに手動で配列をループして、現在の' index'の実行カウントを保つことができますか?そして、 '.get'コールバックで' index'を数え続けるだけです – Akurn

+0

[Possible inside angular.foreachを実装する可能性のある方法はありますか?](http://stackoverflow.com/questions/36997004/is-there-a -possible-way-implemented-promise-inside-angular-foreach) – Maverick

答えて

0

は、このコードを試してみてください -

var deferred = $q.defer(); 
    $http.post('/api/tumblr_primaryblog_name/' + value["post_author"]).then(
     function successCallback(response){ 
      deferred.resolve(response); 
      return deferred.promise; 
     }, 
     function errorCallback(response){ 
      deferred.reject(response); 
      return deferred.promise; 
     }); 
+0

@downvoter:なぜですか? – naveen

+0

私はdownvoteをしませんでしたが、これは実際に質問のどの部分にも答えません。 '$ http.post'はすでに約束を返すので、冗長でもあります。 – Miral

0

一つの方法は、それぞれの呼び出しが完了するのを待つために再帰を使用して実装することです。チェックhereを確認してください。

var postRequestCache = {}; 
var postResponseCache = {}; 
angular.forEach($scope.news.posts, function(value, key) { 
    var author = value["post_author"]; 
    if (!(author in postRequestCache)) { 
     postRequestCache[author] = $http.get('/api/tumblr_primaryblog_name/' + author).then(function(response) { 
      postResponseCache[author] = response.data; 
     }); 
    } 
}); 
$q.all(postRequestCache).then(function() { 
    angular.forEach($scope.news.posts, function (value, key) { 
     var response = postResponseCache[value["post_author"]]; 
     value["post_author_pblog"] = response.response.blog.title; 
    }); 
}); 

あなたはおそらく、いくつかの追加を追加したいと思う:

他の方法は、あなたが例えば、あなたがクエリを実行しようとしているという事実をキャッシュする必要がhere

+1

これはコメントであり、答えではありません。 – naveen

1

を連鎖約束を使用することですエラーチェック。また、postResponseCacheを経由せずに後者のハンドラで直接応答を得ることも可能ですが、これは簡単です。

関連する問題