Javascript 在ajax回调函数之外使用变量

Javascript 在ajax回调函数之外使用变量,javascript,jquery,ajax,Javascript,Jquery,Ajax,在回调函数之外使用全局变量的最佳方法是什么 var icon; $(function(){ $.get('data.xml', function(xml){ icon = xml.documentElement.getElementsByTagName("icon"); //this outputs a value console.log(icon); }); //th

在回调函数之外使用全局变量的最佳方法是什么

    var icon; 
    $(function(){

      $.get('data.xml', function(xml){

           icon = xml.documentElement.getElementsByTagName("icon");
           //this outputs a value
           console.log(icon);
       });
       //this is null
       //How can this maintain the value set above?
       console.log(icon);
    });
console.log(图标)在这一点上没有值。在回调函数中移动处理响应的整个代码

$(function(){

  $.get('data.xml', function(xml) {
       var icon = xml.documentElement.getElementsByTagName("icon");
       console.log(icon);
   });
});

问题是,
$.get
正在对请求进行排队,但没有同步执行请求;它立即返回。JavaScript不是多线程的

您必须在回调函数中执行
console.log(图标)
。在执行该行时,AJAX调用尚未完成


全局
图标
变量将从回调中设置;您的代码在这方面是正确的。

您提供的代码完全有效——事实上,
图标确实“保持”了它的值。问题很可能是
get()
异步运行——仅在从服务器完全加载
'data.xml'
后调用匿名函数。因此,现实世界中的执行顺序如下所示:

  • 调用
    get('data.xml',函数(xml){…})
    (开始加载data.xml)
  • 调用
    console.log(icon)
    icon
    此时仍然为空)
  • (data.xml已完成加载)现在调用匿名函数,该函数将值分配给icon:
    icon=xml.documentElement.getElementsByTagName(“icon”)
  • 如果要在提取“data.xml”后使用
    图标的值执行某些操作,则需要在匿名回调函数中执行。像这样:

    var icon; 
    $(function(){
    
      $.get('data.xml', function(xml){
           icon = xml.documentElement.getElementsByTagName("icon");
           console.log(icon);
       });
    });
    
    祝你好运


    注意:您仍然可以从匿名函数外部的代码中使用
    图标
    ,但您需要等待匿名函数运行后才能访问它。最好的方法是将依赖代码放入自己的函数中,然后从回调函数中调用该函数:

    var icon; 
    $(function(){
    
      $.get('data.xml', function(xml){
           icon = xml.documentElement.getElementsByTagName("icon");
           loadIcon();
       });
    
       function loadIcon() {
           console.log(icon);
           // ... do whatever you need to do with icon here
       }
    });
    

    这样有助于可视化代码

        var icon; 
        $(function(){
            $.get('data.xml', callback); // sends ajax request
            // next line happens immediately unless ajax request is set to synchronous
            console.log(icon); // logs undefined
        });
        function callback(xml){ // onsuccess callback happens
            icon = xml.documentElement.getElementsByTagName("icon");
            console.log(icon); // logs Array
        }
    

    我删除了匿名函数,并将回调放在
    console.log
    之后。正如其他人指出的那样,ajax回调是异步进行的,而javascript则继续执行。

    您想归档什么?它如何维护什么值?你需要更清楚。没有最好的方法可以直接使用它们,它只需要保存xml元素的值。这个问题已经被问了一百万次了。由于$.get是异步的,因此传递给它的函数不会立即执行。因此,当您在调用$.get后调用console.log时,回调尚未被调用。这就是为什么添加一个足够长的超时会起作用(但这将是一个非常讨厌的攻击)我需要在回调函数之外使用变量。@Mike,你不能在回调函数之外使用它。您可以重新构造代码,以便回调函数依次调用您编写的自定义函数。也可以将自定义代码直接放入回调函数中。但是在ajax调用之后无法直接使用它,因为这里的每个人都说它是异步的(可以使调用同步,但这是一个非常糟糕的主意,因为同步ajax可以锁定浏览器)。我试图避免使用第二种解决方案。但看起来这是唯一的出路。更糟糕的是,我不得不添加一个setTimeout函数来让它工作。啊!@迈克,如果你能多发一点关于你在做什么的帖子(或者再问一个问题),我们可以帮助你避免使用计时器。(请让我们帮助您避免这种情况——这里几乎肯定不需要计时器)。@Mike:您的问题是在调用
    addMarkers()
    函数时,google maps没有完全初始化。如图所示,google希望在窗口(或主体)加载事件中创建地图对象,否则会产生“奇怪的行为”。使用jQuery
    $(function(){…})
    将初始化绑定到DOM加载事件,该事件发生在窗口/主体加载事件之前。创建一个新的S.O.问题(在这里发布一个链接,以便我看到),我将帮助您对其进行排序。@Mike:查看jQuery文档以了解更多信息。还可以查看--滚动到底部,它显示了google提供的钩住窗口加载事件并调用初始化函数的方法:
    google.maps.event.addDomListener(窗口“加载”,初始化)
    这种方法应该与jQuery的各种事件挂钩机制可以接受地共存。如果我将代码放在body load事件中并去掉document ready函数,似乎一切都正常。这将是一个很好的时间来研究文档准备、正文负载和窗口负载。谢谢