-1

In below code I have 3 alert() and I want to these alerts respectively fired. first alert(1), second alert(2) and then alert(3) but now because of img.onload() function alert(3) fired before alert(2).

var _URL = window.URL || window.webkitURL;

$("#file").change(function(e) {
var file, img;
if ((file = this.files[0])) {
    img = new Image();
    alert(1)
    img.onload = function() {
         alert(2)
    };
    alert(3)
    img.src = _URL.createObjectURL(file);
}
});

Demo

Is there any way to do this?

mohammad
  • 1,018
  • 2
  • 14
  • 27
  • 1
    Using your current logic, no. The `onload()` is effectively asynchronous. If you need `alert(3)` to appear after `alert(2)`, put it in the onload handler after the `alert(2)` – Rory McCrossan Jun 22 '17 at 08:00
  • Where is the problem , this is fine ? – Nikola Lukic Jun 22 '17 at 08:01
  • Possible duplicate of [Wait for image to be loaded before going on](https://stackoverflow.com/questions/8645143/wait-for-image-to-be-loaded-before-going-on) – Govind Samrow Jun 22 '17 at 08:02

4 Answers4

1

Simply use Promise.

var _URL = window.URL || window.webkitURL;

const asyncOnload = img =>
  new Promise((resolve, reject) => {
    img.onload = () => resolve(alert(2))
    img.onerror = () => reject()
  })

$("#file").change(function(e) {
  var file, img;
  if ((file = this.files[0])) {
      img = new Image();
      alert(1)

      asyncOnload(img).then(() => alert(3))

      img.src = _URL.createObjectURL(file);
  }
});

Try it here

Guillaume L.
  • 61
  • 1
  • 3
-1

Did you try to put the third alert in the onload callback?

var _URL = window.URL || window.webkitURL;

$("#file").change(function(e) {
    var file, img;
    if ((file = this.files[0])) {
        img = new Image();
        alert(1);
        img.onload = function() {
            alert(2);
            alert(3);
        };
        img.src = _URL.createObjectURL(file);
    }
});
Phugo
  • 400
  • 1
  • 10
-1

You can try to add function to call back. snippet example:

var _URL = window.URL || window.webkitURL;
$("#file").change(function(e) {
var file, img;
    if ((file = this.files[0])) {
      img = new Image();
      alert(1);
      img.onload = function() {
          alert(2);
          call();
      };
      img.src = _URL.createObjectURL(file);
   }
});

function call(){
    alert(3);
}
SkyClasher
  • 171
  • 2
  • 11
-1

Well, there is multiple solutions for your problem. The first obvious one is to call your alert in the img.onload function, like this:

img.onload = () => {
   alert(2)
   alert(3)
}

Or, you can simply use the setTimeout function, but it’s more “risky” with slow connection. Hope I fixed your problem .

Arthur Guiot
  • 713
  • 10
  • 25