2014-10-10 136 views
1

我正在处理大型数据文件时出现时间问题。有时,“getFileData(selectedFile)”之后的语句在下载文件之前执行,并且语句失败。我正在考虑一个“暂停”功能,但必须有更好的东西。javascript http请求滞后

$("#dropDown").change(function(){ 
    var selectedFile = $("#dropDown").val(); 
    var text = getFileData(selectedFile); 

    var valueLength = text.constructs[0].data_sections[0].values.length; 
    var errorLength = text.constructs[0].data_sections[0].errors.length; 
    . . . . 
    . . . . 
    . . . . 

}); 

var getFileData = function(fileName){ 

    var xmlhttp = new XMLHttpRequest(); 
    var url = "http://xxx/xxx.php"; 

xmlhttp.onreadystatechange=function() { 
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
     var response = JSON.parse(xmlhttp.responseText.substr(0,xmlhttp.responseText(indexOf("<"))); 
     return response; 
    } 
} 
xmlhttp.open("GET", url + "?q=" + fileName + ".txt", true); 
xmlhttp.send(); 

}

+0

你应该将所有依赖于你的VAR文本的回调函数的代码:xmlhttp.onreadystatechange - 你的XMLHTTP请求是非阻塞[这是很好] - 你通过在这里传递true告诉它是异步的:xmlhttp.open(“GET”,url +“?q =”+ fileName +“.txt”,true); – 2014-10-10 23:52:30

+0

XMLHttpRequest()本质上是异步的。您应该考虑使用回调模式(如pep的回答+1所示)或使用promise。 – JME 2014-10-10 23:59:52

回答

2

你说得对,有一个更好的方法:回调函数。如果你不熟悉回调,下面的代码可能不是最有意义的。我没有测试过它,但它应该起作用,或者至少应该接近。请参阅回调http://www.impressivewebs.com/callback-functions-javascript/

$("#dropDown").change(function(){ 
    var selectedFile = $("#dropDown").val(); 
    var text = getFileData(selectedFile, function(response){ 
    //stuff that should not execute until XMLHttpRequest completes 
    var valueLength = response.constructs[0].data_sections[0].values.length; 
    var errorLength = response.constructs[0].data_sections[0].errors.length; 
    . . . . 
    . . . . 
    . . . . 
    });  
}); 

var getFileData = function(fileName, callback){ 

    var xmlhttp = new XMLHttpRequest(); 
    var url = "http://xxx/xxx.php"; 

    xmlhttp.onreadystatechange=function() { 
     if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
      var response = JSON.parse(xmlhttp.responseText.substr(0,xmlhttp.responseText(indexOf("<"))); 
      callback(response); 
     } 
    } 
    xmlhttp.open("GET", url + "?q=" + fileName + ".txt", true); 
    xmlhttp.send(); 
} 

事实上,你拥有的代码将永远不会工作。您的getFileData函数将始终在您的HTTP请求完成之前返回,因此在您的return声明命中之前将会返回。回调模式对于学习非常有用,并且本质上允许您提供在延迟后执行的代码,无论延迟是由HTTP请求,动画还是由您命名。

+0

谢谢,我欣赏这一课。结果如下。 http://www.wileyallc.com/test/JsonPHPTest2现在,我只需要弄清楚如何在等待数据的同时招待用户。 – wileyken 2014-10-11 01:22:59

0

由于您使用的是jQuery,您不妨使用jQuery ajax()函数。该函数返回一个deferred对象,并且您可以使用deferred.done()方法在AJAX请求完成时执行代码。 done()接受单个参数,这是您在请求完成时要运行的功能。

$("#dropDown").change(function(){ 
    var selectedFile = $("#dropDown").val(); 
    var deferred = getFileData(selectedFile); 
    deferred.done(function (data) { 
     var text = JSON.parse(data.substr(0, data.indexOf("<")); 
     var valueLength = text.constructs[0].data_sections[0].values.length; 
     var errorLength = text.constructs[0].data_sections[0].errors.length; 
     . . . 
    }); 
}); 

var getFileData = function(fileName) { 
    return $.ajax({ 
     url: "http://xxx/xxx.php?q=" + fileName + ".txt" 
    }); 
} 

注意:这将在默认情况下执行GET请求。如果你想要做一个POST,你可以指定在Ajax调用类型:

$.ajax({ 
    url: "http://xxx/xxx.php?q=" + fileName + ".txt", 
    type: "POST" 
});