问题
Okay, so I am writing a little chat system for a project I'm working on. I've been trying to learn AJAX in the process, and all seems to be going well. My AJAX runs a PHP page that opens a directory, and AJAX receives the directory back from the page as an Array (DirectoryList). It then loads another AJAX function over and over until all of the chat logs are appended to the DIV.
My problem is that the ChatLogs are not loaded in the right order.
For example, if I had the Logs:
- 1.txt
- 2.txt
- 3.txt
- 4.txt
They would be appended to the ChatContainer DIV as:
- 2.txt
- 1.txt
- 4.txt
- 3.txt
Instead of the correct order.
Here's my code:
var ChatList = new Array();
var p;
var DirectoryList = new Array();
var ChatString = '';
function loadChat(variable) {
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200) {
DirectoryList = JSON.parse(req.responseText);
var p = variable;
while (p < DirectoryList.length) {
loadLog(p);
p++;
}
}
}
//END REQ1
//Post Chat to DIV
function loadLog(p) {
$.get('chat/log/' + DirectoryList[p], function (data2) {
ChatList.push(data2);
$('#ChatContainer').append(data2);
});
}
//End
req.open('GET', 'process/ReadChatLogs.php', true)
req.send(null);
}
loadChat(0);
回答1:
Ajax is not guaranteed to finish in the same order that you request them because the server may take longer to return one request than it does the next. to solve this, wait until they are all done, then loop over the original collection and append the results. Below is how you could do that with deferred objects.
var ChatList = new Array();
var p;
var DirectoryList = new Array();
var ChatString = '';
function loadChat(variable) {
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200) {
DirectoryList = JSON.parse(req.responseText);
var p = variable;
var defArr = []; // store references to deferred objects
while (p < DirectoryList.length) {
defArr.push(loadLog(p));
p++;
}
$.when.apply($,defArr).done(function(){ // apply handler when all are done
// handle case where only one ajax request was sent
var args = arguments;
if ($.type(args[0]) != "array") {
args = [];
args[0] = arguments;
}
// loop over and ouput results.
var outHTML = "";
$.each(args,function(i){
outHTML += args[i][0];
ChatList.push(args[i][0]);
});
$("#ChatContainer").append(outHTML);
});
}
}
//END REQ1
//Post Chat to DIV
function loadLog(p) {
return $.get('chat/log/' + DirectoryList[p]);
}
//End
req.open('GET', 'process/ReadChatLogs.php', true)
req.send(null);
}
Edit: fixed case where only one ajax request is sent
来源:https://stackoverflow.com/questions/15621306/ajax-is-coming-back-in-the-wrong-order