Javascript function returns before its subroutine finishes
I'm trying to test if urls dynamically passed to image tags would resolve or not. I'm using the following javascript function:
testImageUri = function(src) {
var img = new Image();
var imgStatus = false;
var goodUri = function() {
imgStatus = true;
};
var badUri = function() {
imgStatus = false;
};
img.onload = goodUri;
img.onerror = badUri;
img.src = src;
return imgStatus;
}
The functions badUri and goodUri get called as expected, but they appear to be "late" as the testImageUri function seems to return before they get to change the imgStatus variable.
How do one resolve such probl开发者_Python百科ems in javascript?
How do one avoid them? is there a rule of thumb to recognize situations susceptible to create this?EDIT
Thanks all for your replies. I think I understand what's going on now. I will be implementing the function as described in the first reply, but with an additional parameter for the callback as suggested.Thanks again.
By setting the img.onload and img.onerror, you attach functions to these event handlers. The script will attach them, and when succesful, execute the remainder of the script. As you've already noticed, Javascript does not halt execution until these events actually fire.
Instead of returning the imgStatus (which will probably be used by a new function, which I'll reference to as doSomething
), consider adding this doSomething
function to the event handlers themselves, making it act as a callback function:
testImageUri = function(src) {
var img = new Image();
var imgStatus = false;
var goodUri = function() {
callback_testSuccesful(src);
};
var badUri = function() {
callback_testFailed(src);
};
img.onload = goodUri;
img.onerror = badUri;
img.src = src;
return true; // The event handlers have been added; the return value doesn't say if they fired or not.
}
function callback_testSuccesful(src) { } // Function called when the image loaded
function callback_testFailed(src) { } // Function called when loading failed
You are adding the functions as event handlers to the image element. That means that they are guaranteed to be called after you exit the testImageUri function. No events will be handled as long as you are inside the testImageUri function, so the imgStatus variable will never be updated in time to be returned.
The solution would be to send a callback function into the testImageUri function. When the event occurs you call the callback function. However, as the function returns immediately after setting the image source, you have to declare the img variable outside the function so that it survives after exiting from the function.
var img;
testImageUri = function(src, callback) {
img = new Image();
var goodUri = function() {
callback(true);
};
var badUri = function() {
callback(false);
};
img.onload = goodUri;
img.onerror = badUri;
img.src = src;
}
Try this:
var imageMaker= {
image:null,
imgStatus: false,
goodUri:function() {
this.imgStatus = true;
},
badUri:function() {
this.imgStatus = false;
},
testImageUri:function(src) {
this.image = new Image();
this.image.onload = this.goodUri;
this.image.onerror = this.badUri;
this.image.src = src;
}
}
};
//now fire imageMaker.testImageUri(src)
精彩评论