AngularJS - 通过ASYNC GET请求循环

时间:2017-08-03 12:10:38

标签: javascript angularjs asynchronous

我是Javascript和AngularJS的初学者,我正在尝试执行以下操作:

有一项服务将列表作为URL作为输入,并在本地缓存/存储库自定义服务中查找各自的数据。

  • 如果找到所有内容,则会返回。
  • 如果缺少某些内容,则通过对API进行ASYNC调用来获取缺少的内容。它们也存储在存储库中以供将来使用。

所有接收到的数据都连接成一个本地“数据”变量,并作为单个对象数组发送到控制器。

使用$ .map循环遍历每个URL以获取数据并将其连接到本地“data”变量。循环完成后,它将返回“data”变量。

我知道这不起作用,也是它的原因。但是,我无法弄清楚如何使用ASYNC设计模式实现这一目标。

myService.factory("dataManagerService",["dataRepositoryService","dataFetchService",
    function(dataRepositoryService,dataFetchService)
    {
        var methodObj = {};

        methodObj.getObjData = function(urlList)
        {
            //URLs are used to fetch data from API and also to uniquely identify the fetched data. 
            //urlList is a list/array of URLs for which data is required.

            //Get all objects from data repository which are specified in the URL list.
            var data = dataRepositoryService.getData(urlList);

            //If repository did not have all objects specified from the URL list, fetch the missed objects.
            if (data.length < urlList.length)
            {

                //Get list of URL for which data was received from repository.
                var excludeURLList = $.map(data,
                    function(obj)
                    {
                        return obj.url;
                    }
                );

                //Get list of all URLs from urlList that are missing from excludeURLList
                var fetchUrlList = $.grep(urlList,
                    function(url)
                    {
                        return excludeURLList.indexOf(url) < 0;
                    }
                );

                //Loop through all URLs in fetchUrlList (for which data was not found in the repository)
                $.map(fetchUrlList,
                    function(url)
                    {
                        //Make a GET request to the API
                        dataFetchService.fetchData(url)
                        .then(
                            function(response)
                            {
                                //Add the received response to the repository, so that its available the next time.
                                dataRepositoryService.setData(response.data);

                                //Append missing data to "data" variable
                                data.concat(response.data);
                            }
                        );
                    }
                );
            }
            return data; /* This will be incomplete since it will be returned before all the async calls have been completed. */
        }

        return methodObj;
    }
]);

1 个答案:

答案 0 :(得分:-1)

您将要使用$ q.all()来检索所有URL。这是一篇非常好的文章:https://www.martin-brennan.com/using-q-all-to-resolve-multiple-promises/

你会想做这样的事情:

getObjectList(urlList) {
   var promises =[]
   urlList.map( function(url) { promise.push(getUrl(url) } )
   $q.all(promises).then( function(responses) { assemble what you want to return here}
  )


}

function getUrl(url) {
    var q=$q.defer()
    if (whereever you've stored the data has fetched the url already) {
         return $q.when(the data) 
    } else {
          return $http.get(url).then( function(response) {
              return $q.resolve(response.data)
          }, function (error) { return $q.reject(error) })
    }

}