1

基于 chrome 开发人员工具的断点,我想我正在处理一个我可以弄清楚的范围问题。是我定义函数的方式吗?下面的脚本是一个包含 js 文件和我希望在其他函数中使用的数组 timeStamp,而不必每次都调用我的 loadData 函数。

一旦它离开 for 循环,甚至在离开函数之前,timeStamp 数组就会变得未定义。

var timeStamp = [];  // Want this array to be global

function loadData (url){

        $.getJSON(url, function(json) {

            for (var i=0;i<json.length;i++){
                    timeStamp.push(json[i].TimeStamp);  
                }
                    console.log(inputBITS); //returns the value
            });
        console.log(inputBITS); //undefined
        }

感谢您的任何帮助

4

2 回答 2

6

看起来问题getJSON是异步的。当它执行并完成并且您的代码继续运行时,它仅指示网络操作的开始以检索数据。实际的联网操作要等一段时间后才能完成。

当它完成时,将调用成功处理程序(作为调用的第二个参数指定getJSON())并填充timeStamp数组。只有在调用成功处理程序之后,timeStamp数组才有效。

因此,您不能timeStamp在紧随getJSON()调用之后的代码中使用该数组(它尚未被填充)。如果其他代码需要该timeStamp数组,您应该从成功处理程序中调用该代码或使用其他一些计时机制来确保使用该数组的代码在调用成功处理程序并且该数组timeStamp之前不会尝试使用它timeStamp已被填充。

可以使一些 Ajax 调用同步而不是异步,但这通常是一个非常糟糕的主意,因为它会在整个网络操作期间锁定浏览器,这对查看者非常不友好。修复编码逻辑以与异步网络一起工作要好得多。

像这样的 ajax 调用的典型设计模式如下:

function loadData (url){

    $.getJSON(url, function(json) {
        // this will execute AFTER the ajax networking finishes
        var timeStamp = [];
        for (var i=0;i<json.length;i++) {
                timeStamp.push(json[i].TimeStamp);  
        }
        console.log(timeStamp);
        // now call other functions that need timeStamp data
        myOtherFunc(timeStamp);
     });
     // this will execute when the ajax networking has just been started
     //
     // timeStamp data is NOT valid here because 
     // the ajax call has not yet completed
     // You can only use the ajax data inside the success handler function
     // or in any functions that you call from there
}
于 2012-04-19T21:25:14.063 回答
2

还有一个不懂基本 AJAX 的人……

getJSON异步的。意思是,代码在函数调用之后和 JSON 请求成功返回之前一直运行。

您可以通过强制请求与适当的标志同步来“修复”此问题,但由于许多原因,这是一个非常糟糕的主意(其中至少是您违反了A �JAX 的基本思想)。最好的方法是记住 AJAX 是如何工作的,而是将所有应该在 AJAX 返回时执行的代码放在正确的位置。

于 2012-04-19T21:25:32.860 回答