Petr Bečka
Petr Bečka

Reputation: 794

continue in for loop after function is done JavaScript

I have found behaviour that makes me trouble in JavaScript. I have two functions:

var show_uploaded = function( data_photo ) that gets informations about uploaded photos as a parameter,

function exif_like(path){/*working with my image*/ console.log('exif_like END'); }
that gets path to every single one uploaded photo as a parameter.

I made code like this:

var show_uploaded = function( data_photo ){
    for( var z = 0; z < data_photo.length; z++ ){ 
       var send_image_name = uploaded_photo[z].name;
       $.ajax({
            data: { compare : send_image_name },
            url: 'get_panorama.php',
            method: 'POST', // or GET
            success: function( path ){
                exif_like( path );
                console.log('FOR LOOP END');
            }
       });
    }
};

But what I see in console is that "FOR LOOP END" log is displayed before "exif_like END" log. And this causes some unpredictable behaviour in my code.

Is there any solution how to continue for loop after exif_like() function is done?

Upvotes: 4

Views: 2630

Answers (3)

Andriy Ivaneyko
Andriy Ivaneyko

Reputation: 22071

Replace for loop to while loop, condition is until data_photo not empty, prior starting while loop create flag variable which would be boolean identifier that ajax success handler finished and next ajax can be sent. See code below with commented changes :

var show_uploaded = function( data_photo ){
  // Create flag 
  var flag = true;
  var length = data_photo;

  // continue loop execution until data_photo not empty
  while (length){
    if(flag){
        var send_image_name = uploaded_photo[--length].name;
        // Set flag to false, until success executed
        flag = false;
        $.ajax({
            data: { compare : send_image_name },
            url: 'get_panorama.php',
            method: 'POST', // or GET
            success: function( path ){
                exif_like( path );
                console.log('FOR LOOP END');
                // We are ready to perform next ajax, set flag to true.
                flag = true;
            },
            error: function( path ){
                // Error or not we have to set flag to true to allow further iterating
                flag = true;
            }
       });
   }
}
};

Upvotes: 1

ak_
ak_

Reputation: 2815

If you are trying to have exif_like() do things in between Ajax calls, just have your exif_like() function call the next Ajax request when it finishes.

Using test data from json placeholder, something like this would work:

JavaScript

uploaded_photo = [{name: 1},{name: 2},{name: 6},{name: 8},{name: 9},{name: 11},{name: -1}]
pointer = 0;

function exif_like(path){
    /*working with my image*/ 
  obj = JSON.parse(path)
  if(obj.length > 0) {
    console.log('\t\tdata returned:'+obj[0].id + ' '+obj[0].title)
        console.log('exif_like END for '+obj[0].id);
  } else {
    console.log('\t\tNo data returned')
        console.log('exif_like END');  
  }

  /* Code here can be executed before the next Ajax call */
  console.log('Do stuff before the next ajax call...')

  pointer++;
  if(pointer < uploaded_photo.length) {
    show_uploaded();
  }
}

var show_uploaded = function(){
    console.log('---Start of Ajax call---');

  $.ajax({
    data: { id : uploaded_photo[pointer].name },
    url: 'https://jsonplaceholder.typicode.com/posts',
    method: 'GET', 
    complete: function( xhr ){
        console.log('---End of Ajax call---');
      exif_like( xhr.responseText );
    }
  });
};

show_uploaded()

Output

---Start of Ajax call---
---End of Ajax call---
data returned:1 sunt aut facere repellat provident occaecati excepturi optio reprehenderit
exif_like END for 1
Do stuff before the next ajax call...
---Start of Ajax call---
---End of Ajax call---
data returned:2 qui est esse
exif_like END for 2
Do stuff before the next ajax call...
---Start of Ajax call---
---End of Ajax call---
data returned:6 dolorem eum magni eos aperiam quia
exif_like END for 6
Do stuff before the next ajax call...
---Start of Ajax call---
---End of Ajax call---
data returned:8 dolorem dolore est ipsam
exif_like END for 8
Do stuff before the next ajax call...
---Start of Ajax call---
---End of Ajax call---
data returned:9 nesciunt iure omnis dolorem tempora et accusantium
exif_like END for 9
Do stuff before the next ajax call...
---Start of Ajax call---
---End of Ajax call---
data returned:11 et ea vero quia laudantium autem
exif_like END for 11
Do stuff before the next ajax call...
---Start of Ajax call---
---End of Ajax call---
No data returned
exif_like END

JS Fiddle Example: https://jsfiddle.net/igor_9000/wwj11udx/3/

Hope that helps!

*Edit: Updated code to use the complete function instead, in the event there are requests that don't succeed.

Upvotes: 1

guest271314
guest271314

Reputation: 1

If the remainder of processes return expected results, and exif_like actually only performs console.log() you could try using $.when()

$.when(exif_like( path )).then(function() {console.log("FOR LOOP END")})

Upvotes: 2

Related Questions