panda
panda

Reputation: 1344

Execution time of for loop over elements is faster than the inner AJAX call can respond

I have function LoadTempMovieList(), and need to load movies from sessionStorage. But it seems that the execution time of the for loop is faster than the AJAX call I'm making can respond, so the order of final output is not correct sometimes. How can I solve this problem?

function LoadTempMovieList(){
  var obList = [];
  if(sessionStorage.struct != null){
    alert(sessionStorage.struct);
    obList = sessionStorage.struct.split(",");
    for(var i=0; i<obList.length;i++){
      MovieLoader(obList[i],"movie");
      //it use setTimeOut(), the problem also present 
    }
  }
}

update

function MovieLoader(name,type,movieArray){
  $.ajax({
    ...
    data:{shortName:name,type:type},
    dataType:'html',
    success:function (html){
      if(html!="0"){
        ...
      }else{
        ...
      }
    }
  });
}

Upvotes: 2

Views: 272

Answers (2)

jcolebrand
jcolebrand

Reputation: 16035

I'm introducing recursion to load the objects in the order they're in the array. I'm also introducing some code that you may not feel you need to include to verify that we've got an array (in case some errant other function calls this, or whatever)

function LoadTempMovieList(){
  var obList = [];
  if(sessionStorage.struct != null){
    alert(sessionStorage.struct);
    obList = sessionStorage.struct.split(",");

    LoadMoviesInOrder(obList);
  }
}

function LoadMoviesInOrder(movies){
  if( Object.prototype.toString.call( movies ) === '[object Array]' ){
    //get the very first object in the array, take it off the array
    var movie = movies.shift();
    MovieLoader(movie,"movie",movies);
  }
}

function MovieLoader(name,type,movieArray){
  $.ajax({
    ...
    data:{shortName:name,type:type},
    dataType:'html',
    success:function (html){
      if(html!="0"){
        ...

        if (movieArray.length) { //test to see if there are more movies left by using truthiness
          //wait 50 ms and call this function again, so that we achieve recursion
          setTimeout(function(){LoadMoviesInOrder(movieArray); }, 50);
        }
      }else{
        ...
      }
    }
  });
}

Upvotes: 2

jfriend00
jfriend00

Reputation: 707746

If your ajax call that you refered to in your original question (before someone else edited that out) is asynchronous, then you will have to use the completion function of the ajax call to trigger the next call to MovieLoader.

Since ajax calls take an indeterminate amount of time to complete, it is not completely reliable to try to use some sort of setTimeout() to guess how long an ajax call takes. The only 100% reliable way to sequence the ajax results is to sequence the ajax calls and not launch the next ajax call until the first one has completed, etc...

You don't show us your actual ajax call so we can't be more specific on the best way to implement this.

Upvotes: 2

Related Questions