kelanyll
kelanyll

Reputation: 19

For loop is returning promises in the wrong order

I'm calling a function a certain amount of times to fetch individual src attributes from an array of lists. The src attributes are coming back in the wrong order. I've tried using setTimeout but that returns an array of nulls and my own pause function just returns the same order of list just a certain amount of milliseconds later.

The function is called here:

  myLoopingFunction: function(links) {
    var pause = function sleep(milliseconds) {
      var currentTime = new Date().getTime();
      while (currentTime + milliseconds >= new Date().getTime()) {
      }
    }
    var deferred = $q.defer();
    var promise = deferred.promise;
    var src = [];
    for (var i = 0;i < links.length;i++) {
      getSrc(links[i]).then(function(response) {
        src.push(response)
      });
    }
    deferred.resolve(src);
    return deferred.promise;
  }

EDIT: This is the function:

     var getSrc = function(links) {
      return $q.all(links.map(function(link){
         return $http.get(link.Address);
     })).then(function(results){
         var src = results.map(function(result){
           var tmp = document.implementation.createHTMLDocument();
           tmp.body.innerHTML = result.data;
           var video = $(tmp.body.children).find('#definitionblock iframe');
           var video_src = $(video[0]).attr("src");
           return video_src;
         });
     })
  };

It's being called here:

      bslLogin.getSrc($scope.links).then(function(response) {
        $scope.videos = response;
        console.log($scope.videos);
      })

It's now returning undefined. I can see via console.logs that the chain of functions is producing the right result till the end where it returns undefined. It doesn't even recognise the return value as an array.

Upvotes: 0

Views: 304

Answers (1)

Meiko Rachimow
Meiko Rachimow

Reputation: 4724

You have to use $q.all() to get the results of your "http-promises" in the expected order. In your code the http calls are running asynchronous (concurrently) and the callback handlers, which add responses to the array, too.

This could be a solution with an array of promises (be careful, the code is untested):

$q.all(links.map(function(link){
    return $http.get(link.Address);
})).then(function(results){
    var src = results.map(function(result){
        var tmp = document.implementation.createHTMLDocument();
        tmp.body.innerHTML = response.data;
        var video = $(tmp.body.children).find('#definitionblock iframe');
        var video_src = $(video[0]).attr("src");
        console.log(video_src);
        return video_src;
    });
    return src;
})

Upvotes: 1

Related Questions