2017-08-03 102 views
0

我在Javascript和AngularJS一个初学者,我试图做如下:AngularJS - 通过异步GET循环请求

有接受一个列表,网址为输入,找到在当地各自的数据服务缓存/存储库自定义服务。

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

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

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

我知道这不起作用,也是它的原因。但是,我无法弄清楚如何使用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

你会想用$ q.all()来检索所有网址。下面是关于这一个相当不错的文章: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) }) 
    } 

} 
+0

感谢没有任何解释的downvote。这很有帮助。 –

+0

这对我有效。但是,你能告诉我为什么我们在getUrl()方法中使用$ q.defer()吗?只是$ http的结果本身就是一个承诺,我们需要$ q.all()方法。 –

+0

谢谢。我很高兴工作。我使用$ q.defer的唯一原因是我只能返回数据对象,仍然包含在承诺中。如果只返回$ http.get,那么你会得到一个完整的响应对象。 –