Javascript函数在其子例程完成之前返回

时间:2009-11-05 11:19:51

标签: javascript

我正在尝试测试动态传递给图片代码的网址是否会解析。我正在使用以下javascript函数:

    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;
    }

函数badUri和goodUri按预期调用,但它们似乎“迟到”,因为testImageUri函数似乎在它们更改imgStatus变量之前返回。

如何在javascript中解决此类问题? 如何避免它们?
是否有一个经验法则来识别容易产生这种情况的情况?

修改
感谢大家的回复。我想我明白现在发生了什么。我将按照第一个回复中的描述实现该功能,但建议使用附加的回调参数。

再次感谢。

3 个答案:

答案 0 :(得分:4)

通过设置img.onload和img.onerror,可以将函数附加到这些事件处理程序。脚本将附加它们,并在成功时执行脚本的其余部分。 正如您已经注意到的那样,在这些事件实际触发之前,Javascript不会暂停执行。

不要返回imgStatus(可能会被新函数使用,我将其引用为doSomething),而是考虑将此doSomething函数添加到事件处理程序本身,使其成为充当回调函数:

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

答案 1 :(得分:2)

您正在将函数作为事件处理程序添加到image元素。这意味着在退出testImageUri函数后保证可以调用它们。只要您在testImageUri函数中,就不会处理任何事件,因此imgStatus变量永远不会及时更新以便返回。

解决方案是将回调函数发送到testImageUri函数中。当事件发生时,您调用回调函数。但是,由于函数在设置图像源后立即返回,您必须在函数外部声明img变量,以便在退出函数后它能够存活。

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;
}

答案 2 :(得分:2)

试试这个:

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)