0

我正在尝试从 Javascript 函数中设置 JSON 对象并将其用作另一个函数中的参数,但是这个 obj 在函数之外没有任何值。我在函数之外创建了这个 json 对象:

var obj = {"Level":0, "Index":0, "Count":0, "AABB":[], "Point":[], "Children":[]};

然后

function loadXMLDoc()
  {  
   if(window.XMLHttpRequest){
      xmlhttp=new XMLHttpRequest();
   } else {
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
   }
   xmlhttp.onreadystatechange=function(){
      if(xmlhttp.readyState==4 && xmlhttp.status==200){
        var string = xmlhttp.responseText;
        obj = JSON.parse(string);
        document.getElementById("myDiv").innerHTML = obj.Children;
      }
   }
   xmlhttp.open("GET","r0.json",true);
   xmlhttp.send();

   return obj;  
  }

但是在我调用函数并传递 obj 之后,如下所示:

    var obj = loadXMLDoc();
    initGL(canvas);
    initShaders();
    initBuffers(obj);

它不能将值传递给函数 initBuffers。为什么会发生这种情况,我该如何解决?谢谢。

4

4 回答 4

2

当你说你不能作为参数传递时,我不确定你的意思obj,但要意识到你的onreadystatechange处理程序是在你调用之后异步调用initBuffers的。也许,当解析 JSON 响应时,您需要从处理程序内部调用初始化例程。

于 2013-04-06T03:46:14.450 回答
0

由于@akonsu 所说的(同步性质onreadystatechange),loadXMLDoc()当您的 init 函数运行时仍将运行。因此,您的obj变量在运行时尚未定义initBuffers(obj)

一个简单的解决方案是将回调添加到loadXMLDoc()

function loadXMLDoc(objParsed)
  {  
   ...
   xmlhttp.onreadystatechange=function(){
      if(xmlhttp.readyState==4 && xmlhttp.status==200){
        var string = xmlhttp.responseText;
        obj = JSON.parse(string);
        document.getElementById("myDiv").innerHTML = obj.Children;
        objParsed(obj);
      }
   }
   xmlhttp.open("GET","r0.json",true);
   xmlhttp.send(); 
  }

并像这样使用它(假设initGL()并且initShaders()不依赖 的结果initBuffers()):

loadXMLDoc(initBuffers);
initGL(canvas);
initShaders();

顺便说一句,您似乎正在更改 的值obj

obj = JSON.parse(string);

因此,当您稍后尝试访问它时,除非您是有效的 JSON 并且具有根目录下的属性,obj.Children否则它将不存在。它还将完全覆盖您在脚本顶部设置的值。xmlhttp.responseTextChildren

于 2013-04-06T04:06:35.937 回答
0

就像@akonsu 所说的那样,您的 loadXMLDoc 函数的返回是在 ajax 调用完成之前调用的,因为该调用是异步的,所以当您执行 ajax 时,会使用该调用创建另一个进程,然后当前进程(使用函数 loadXMLDoc)不关心,调用结束时只调用 onreadystatechange 函数内的代码,所以我建议您创建一个函数回调,执行 ajax onreadystatechange 内的代码,如下所示:

function loadXMLDoc()
  {  
   if(window.XMLHttpRequest){
      xmlhttp=new XMLHttpRequest();
   } else {
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
   }
   xmlhttp.onreadystatechange=function(){
      if(xmlhttp.readyState==4 && xmlhttp.status==200){
        var string = xmlhttp.responseText;
        var obj = JSON.parse(string);
        document.getElementById("myDiv").innerHTML = obj.Children;
        SOME_CALLBACK(obj)  
      }
   }
   xmlhttp.open("GET","r0.json",true);
   xmlhttp.send();

   //return obj;  no needed any more
  }

function SOME_CALLBACK(obj){
    initGL(canvas);
    initShaders();
    initBuffers(obj);
}

因此,SAVE_CALLBACK 函数通过这种方式接收异步 obj 数据并使用这些数据。

于 2013-04-06T04:13:02.907 回答
0

函数内部的变量绑定到该特定函数并且不能从函数外部访问,除非它们在包含该变量的函数内或者如果该变量设置为全局变量。

如果它只有几个对象,那么一种肮脏的方法是创建一个使用全局容器的跨度。

于 2013-04-06T04:23:43.237 回答