函数外部的javascript数组为空

函数外部的javascript数组为空,javascript,arrays,Javascript,Arrays,我有如下JavaScript代码: var buffer=new Array(); function fetchData(min,max){ var ajaxReq = new XMLHttpRequest(); ajaxReq.onreadystatechange = function(){ if (ajaxReq.readyState === 4) { if (ajaxReq.status === 200) { buffer

我有如下JavaScript代码:

var buffer=new Array();

function fetchData(min,max){
    var ajaxReq = new XMLHttpRequest(); 
    ajaxReq.onreadystatechange = function(){
    if (ajaxReq.readyState === 4) {
        if (ajaxReq.status === 200) {
            buffer= ajaxReq.responseText;
            console.log(buffer)//this logs an array to console
        } else {
            console.log("Error", ajaxReq.statusText);
        }
    }
    };
    ajaxReq.open('GET', "server/controller.php?min="+min+"&max="+max, true); 
    ajaxReq.send();
}

fetchData(1,100);
console.log(buffer);//this log an empty array
两个不同结果的日志,我做错了什么?谢谢你的指点。

是异步的。这意味着末尾的console.log(buffer)是在Ajax请求响应之前执行的

您应该将方法更改为:

function fetchData(min,max,callback){
  var ajaxReq = new XMLHttpRequest(); 
  ajaxReq.onreadystatechange = function(){
    if (ajaxReq.readyState === 4) {
      if (ajaxReq.status === 200) {
        buffer= ajaxReq.responseText;
        callback();
        //console.log(buffer)//this logs an array to console
      } else {
        console.log("Error", ajaxReq.statusText);
      }
     }
  };
  ajaxReq.open('GET', "server/controller.php?min="+min+"&max="+max, true); 
  ajaxReq.send();
}

fetchData(1,100,function(){
    console.log("My Ajax request has successfully returned.");
    console.log(buffer);
});

对我来说似乎是对的。缓冲区在启动时是空的,并且直到异步调用完成后才会设置,因此,即使您在第二个console.log之前获取数据,但在它显示空缓冲区之前,您不会收到数据。

这是异步的。因此,您的流程如下所示:

var buffer=new Array();

function fetchData(min,max){
    var ajaxReq = new XMLHttpRequest(); 
    ajaxReq.onreadystatechange = function(){
    if (ajaxReq.readyState === 4) {
        if (ajaxReq.status === 200) {
            buffer= ajaxReq.responseText;
            console.log(buffer)//this logs an array to console
        } else {
            console.log("Error", ajaxReq.statusText);
        }
    }
    };
    ajaxReq.open('GET', "server/controller.php?min="+min+"&max="+max, true); 
    ajaxReq.send();
}

fetchData(1,100);
console.log(buffer);//this log an empty array
  • 调用
    fetchData()
  • 发送ajax请求,注册一个
    onreadystatechange
    回调
  • fetchData()
    完成并返回
  • 缓冲区已注销,但尚未包含任何内容
  • 稍后,ajax请求完成并触发回调
  • 回调将对象放入数组中
  • buffer
    get从回调中注销,您可以看到它现在包含了项

  • 因此,只有当您点击第一个console.log时,您才会启动异步请求。但它实际上在很久之后就结束了。

    这里有几个问题。当ajax调用完成时,在设置变量之前已经执行了第二个console.log

    另外,您没有将
    缓冲区
    变量用作
    数组
    MDN:

    第三个参数用于告诉浏览器是否应使请求异步。您将其设置为true,因此它将是异步的。
    异步基本上意味着发送请求,同时执行其他代码。因此,它启动请求,并在等待响应时记录缓冲区:在请求完成之前。如果要记录内容,请在onreadystatechange事件中执行,或将第三个参数(async)设置为false。

    您正在尝试在执行AJAX请求之前
    log()
    缓冲区。要解决这个问题,您的
    fetchData
    函数需要处理
    回调
    函数

    var buffer=new Array();
    
    function fetchData(min,max, callback){
        var ajaxReq = new XMLHttpRequest(); 
        ajaxReq.onreadystatechange = function(){
        if (ajaxReq.readyState === 4) {
            if (ajaxReq.status === 200) {
                buffer= ajaxReq.responseText;
                console.log(buffer)//this logs an array to console
                if(typeof callback == 'function'){
                    callback.call(this);
                }
            } else {
                console.log("Error", ajaxReq.statusText);
            }
        }
        };
        ajaxReq.open('GET', "server/controller.php?min="+min+"&max="+max, true); 
        ajaxReq.send();
    }
    
    fetchData(1,100, function(){
        console.log(buffer);
    });
    

    这是最基本的实现,只有在AJAX响应成功时才能工作。

    函数
    fetchData
    中的
    buffer
    变量是有条件设置的。您确定
    ajaxReq.status
    ajaxReq.readyState
    等于您想要的值吗?不将缓冲区用作数组是什么意思,我如何将其用作数组,谢谢您的帮助。
    buffer.push(ajaxReq.responseText)
    会将响应文本推到数组的末尾ajaxReq.responseText是一个多维数组,如何将其所有子数组添加到缓冲区?是的,但是用户必须等待Ajax响应,从而锁定页面。即使现在的反应似乎很快,也难免会有不快的时候。简而言之,不要使Ajax请求同步。