1

我知道这个问题已经被问过好几次了,但在之前的任何问题中,我似乎都找不到适合我的解决方案。我有一个在我的 HTML 页面加载完成时设置的变量,但有时当我的代码尝试访问该变量时,它说它是未定义的。我不知道为什么,因为我相信我正在等待一切正常加载。这个异常似乎是随机发生的,因为大多数时候所有代码都运行良好。这是我的代码的简化版本:

var globalVar;

function initStuff(filePath) {
    // I wait till the HTML page is fully loaded before doing anything
    $(document).ready(function(){
        var video = document.getElementById("videoElementID");

        // My parseFile() function seems to run smoothly
        var arrayOfStuff = parseFile(filePath); 

        if (arrayOfStuff == null) {
            console.error("Unable to properly parse the file.");
        } else {
            setGlobalVariable(arrayOfStuff);
            video.addEventListener("play", updateVideoFrame, false);
        }
    });
}

function setGlobalVariable(arrayOfStuff) {
    window.globalVar = arrayOfStuff;
}

function updateVideoFrame() {
    // A bunch of other code happens first

    // This is the line that fails occasionally, saying 
    // "window.globalVar[0].aProperty.anArray[0] is undefined"
    var test = window.globalVar[0].aProperty.anArray[0].aProperty;
}

我能想到的唯一可能导致此问题的是某种同步问题。不过,我不明白为什么会这样。请帮忙!

编辑:

如果异步问题来自我的parseFile(xmlFile)方法,这就是我在那里做的事情。我认为这不可能导致问题,因为我强制该方法同步发生,但万一我错了,这里是:

function parseKML(xmlFile) {
    var arrayOfStuff = new Array();

    // Turn the AJAX asynchronicity off for the following GET command
    $.ajaxSetup( { async : false } );
    // Open the XML file
    $.get(xmlFile, {}, function(xml) {
        var doc = $("Document", xml);   
        // Code for parsing the XML file is here
        // arrayOfStuff() gets populated here
    });

    // Once I'm done processing the XML file, I turn asynchronicity back on, since that is AJAX's default state
    $.ajaxSetup( { async : true } );

    return arrayOfStuff;
}
4

2 回答 2

2

您应该在代码中做的第一件事是弄清楚以下部分的哪一部分:

window.globalVar[0].aProperty.anArray[0]

未定义。

由于您有多个链式属性引用和数组引用,因此链中可能有许多不同的位置。我建议要么在您的参考之前设置一个断点,它会检​​查其中的内容,或者使用几个console.log()语句来输出结构的每个嵌套部分,以便找出您的问题所在。

console.log("globalVar = " + globalVar);
console.log("globalVar[0] = " + globalVar[0]);
console.log("globalVar[0].aProperty = " + globalVar[0].aProperty);
console.log("globalVar[0].aProperty.anArray = " + globalVar[0].aProperty.anArray);
console.log("globalVar[0].aProperty.anArray[0] = " + globalVar[0].aProperty.anArray[0]);

如果问题是globalVar尚未设置,那么您有时间问题或初始化问题。

如果问题是未设置其他属性之一,那么您没有使用您认为的初始化 globalVar。

您可能还希望编写代码更具防御性,以便在您的某些数据设置不正确时优雅地失败。

于 2012-05-17T23:39:20.740 回答
1

您需要使用防御性编程。 http://www.javascriptref.com/pdf/ch23_ed2.pdf

例子:

var video = document.getElementById("videoElementID") || 0;

-

if( video && video.addEventListener ){
    video.addEventListener("play", updateVideoFrame, false);
}

这是您的代码的另一个版本。

window.globalVar = globalVar || [];
function setGlobalVariable(arrayOfStuff) {
    window.globalVar = arrayOfStuff;
}
function updateVideoFrame() {
    // A bunch of other code happens first

    // This is the line that fails occasionally, saying
    // "window.globalVar[0].aProperty.anArray[0] is undefined"
    if( window.globalVar ){
        var g = window.globalVar || [];
        var d = (g[0] || {})["aProperty"];
        // etc...
    }else{
        console.error( "test error." );
    }

}
function initStuff(filePath) {
    // I wait till the HTML page is fully loaded before doing anything
    $(document).ready(function () {
        var video = $("#videoElementID");

        // My parseFile() function seems to run smoothly
        var arrayOfStuff = parseFile(filePath) || [];

        if (arrayOfStuff == null || video == null ) {
            console.error("Unable to properly parse the file.");
        } else {
            setGlobalVariable(arrayOfStuff);
            video.bind("play", updateVideoFrame);
        }
    });
}
于 2012-05-17T23:36:51.913 回答