Search code examples
javascriptasynchronouswinjsself-invoking-function

How to pass a local variable to a callback while getting something returned by the calling function?


I have a problem with a async callback in a loop. I call a asynchronous function on one of Window's file objects to get further informations about it (getImagePropertiesAsync()) and save these to a database to make further access faster. I need the values that are returned by that functions as well as the value i had when I called getImagePropertiesAsync().

for (var i = 0; i < picsGiven.length; i++) {
  picsGiven[i].properties.getImagePropertiesAsync().then(function(prop){
    settings.values["geoLat" + i2] = props.latitude;
    settings.values["geoLon" + i2] = props.longitude;
    settings.values["geoDate" + i2] = props.dateTaken;
    i2++;
  })
}

Because of the asynchronous execution, the pairs three values got saved in the wrong order. I already worried about that problem by the time I was writing that. Next try.

for (var i = 0; i < picsGiven.length; i++) {
  picsGiven[i].properties.getImagePropertiesAsync().then((function(prop, i2){
    settings.values["geoLat" + i2] = props.latitude;
    settings.values["geoLon" + i2] = props.longitude;
    settings.values["geoDate" + i2] = props.dateTaken;
  })(undefined, i))
}

Now, I got i correctly, but props is undefined. (Logically).

How can I possibly get i correctly while preserving props? Thanks in advance!


Solution

  • (Untested) something like this:

    function mk_handleImagePropertiesAsync(ival) {
      return function(prop) {
        settings.values["geoLat" + ival] = prop.latitude;
        settings.values["geoLon" + ival] = prop.longitude;
        settings.values["geoDate" + ival] = prop.dateTaken;
      }
    }
    
    for (var i = 0; i < picsGiven.length; i++) {
      picsGiven[i]
        .properties
        .getImagePropertiesAsync()
        .then(mk_handleImagePropertiesAsync(i));
    }
    

    Scoping issue! The for-loop does not introduce a new block-scope as in C/C++. The inline function in your loop will always get the same value of i2 (its initial value!)