Wh1T3h4Ck5
Wh1T3h4Ck5

Reputation: 8509

Make function work synchronously (wait local events to get fired)

I'm having problems with JavaScript logic. When we have a function that needs data from event-handler to generate result, is it possible to get that data back to function? For example, if we call Image() object or FileReader() inside and wait for its load event to get fired in order to generate proper return result.

Simple example:

function imageSize(filename) {
  funcResult = false;
  var img = new Image();
  img.onload = function() {
    myResult = { 
      width: img.width,
      height: img.height
      }
    }
  img.src = filename;
  return funcResult;
}

Course, it doesn't work because load fires asynchronously after function has already been executed. But is there some workaround to make function stop and listen which is my main goal.

Or bit more complex example (that also can't work for same reason).

function getImageSize(file) {
  res = false;
  if (window.FileReader) {
    var fileReader = new FileReader();
    fileReader.onload = function() {
      var img = new Image();
      img.onload = function() {
        res = {
          width  : img.width,
          height : img.height
          };
        }
      img.src = this.result;
      }
    fileReader.readAsDataURL(file);
  }
  return res;
}

Usage example:

var imageSize = getImageSize(myFileInput.files[0]);

and handling result as (perfect: wait)

if (!imageSize)
  console.log('error');
else
  console.log(imageSize.width + 'x' + imageSize.height);

or (alternative: from event handler)

imageSize.onload = function() {
  console.log(this.width + 'x' + this.height);
  }

I'd like to make this job linear (sync) and wait for proper event handlers inside to fire, not moving job outside of function scope (especially not to global level).

My goal is to make this a one-function job, or the worst case, to define some load event of that function and listen for result so my strict question is "is this somehow possible and if it is, how?"

I understand how events work and know well that this approach is wrong but that's just an illustration what I was trying to accomplish during last few days.

Upvotes: 1

Views: 2090

Answers (1)

tymeJV
tymeJV

Reputation: 104775

Use a callback inside your function to get the size:

function imageSize(filename, callback) {
    funcResult = false;
    var img = new Image();
    img.onload = function() {
        var myResult = { 
            width: img.width,
            height: img.height
        }
        callback(myResult)
    }
    img.src = filename;
}

And use it:

imageSize("test.jpg", function(sizeAttributes) {
    console.log(sizeAttributes);
});

Upvotes: 5

Related Questions