在继续之前如何让foreach循环等待$ http.get完成?

时间:2016-05-04 04:39:28

标签: javascript angularjs foreach

我似乎无法让代码在继续之前暂停并等待$ 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 CACHEIN CACHE日志语句。

所以问题是,在继续之前,foreach循环如何等待$ http.get完成?

3 个答案:

答案 0 :(得分:1)

您需要缓存您即将进行查询的事实,例如:

this.url = req.protocol + '://' + "myDomain.com" + req.originalUrl

您可能希望添加一些额外的错误检查。另请注意,可以直接在后一个处理程序中获取响应,而无需通过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; }); }); ,但这更容易。

答案 1 :(得分: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;
        });

答案 2 :(得分:0)

一种方法是使用递归来等待每个调用完成。检查here

其他方式是使用promise chaining here