2014-10-10 89 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" 
});