Ich weiß, dass das A in AJAX asynchrone bedeutet, und als solche gibt es keine Garantie, in welcher Reihenfolge meine Antworten zurückkommen, in der Tat ist die größte Payload vernünftig zu erwarten als letztes zurückkommen.Wie ruft JavaScript/Callback-Funktionen auf mehrere AJAX-Antworten
Meine Frage betrifft jedoch die Rückrufe. Manchmal, wenn ich bemerke, dass meine Antworten in einer anderen Reihenfolge, in die sie gesendet wurden, zurückkommen, wird der "falsche" Rückruf aufgerufen.
Nehmen Sie die folgende Funktion. Es gibt einige Werte (rangesize, dropskus, limit)
(kommentiert unten), die für jeden Aufruf eindeutig sind und im Erfolgsrückruf für jeden definiert sind. Wenn ich das Skript ausführen und 5 Anrufe senden, wenn sie in einer anderen Reihenfolge zurückkommen, an die sie gesendet wurden. Nehmen wir an, die größte Antwort war der 2. Aufruf, die Antwort kommt als letzte zurück und ruft auch die letzte Callback-Funktion auf.
Also meine Frage:
Does oder sollte JavaScript/jQuery wissen, welche Callback-Funktion aufzurufen, wenn mehrere Antworten zurückkehrt?
Oder wäre es besser für mich synchrone Anrufe zu verwenden?
Andere Notizen: Beim Debuggen in Chrome habe ich festgestellt, dass die Konsolenprotokolle der Antworten sagen filename.js:linenumber
. Während zuvor, wenn ich mehrere Ajax-Aufrufe verwendet habe, die Konsolenprotokolle sagen VM12*:linenumber
. Ich weiß nicht, ob das etwas mit dem Problem zu tun hat, mit dem ich konfrontiert bin, aber ich habe bemerkt, dass in diesem Fall immer die richtigen Callbacks aufgerufen wurden.
function generateReview(){
var subcategories = subcatstring.split(",");
$("#rangereviewtable").html("");
$("#rangereviewtable").append(thead);
var i = 0;
var iterations = subcategories.length;
$.each(subcategories, function(key, value) {
var postdata = {group: group,
class: rrclass,
category: category,
subcategory: value,
period: period,
periodval: periodval,
stores: storesarray};
console.log(postdata);
$.ajax({
url: "ajaxrangereview.php",
type: "post",
dataType: 'json',
data: postdata,
success: function (response) {
//VALUES UNIQUE TO EACH CALL
var rangesize = parseInt($("#rangesize" + i).text());
console.log("range size: " + rangesize);
var dropskus = parseInt($("#dropskus" + i).text());
console.log("dropskus: " + dropskus);
var limit = rangesize - dropskus;
console.log("limit: " + limit);
console.log(response);
var rrtable = "";
$.each(response, function(i, item) {
rrtable += "<tr>";
rrtable += "<td class='rangereviewtext'>" + item.category + "</td>";
rrtable += "<td class='rangereviewtext'>" + item.subcategory + "</td>";
rrtable += "<td class='rangereviewtext'>" + item.brand + "</td>";
rrtable += "<td class='rangereviewtext'>" + item.sku + " - " + item.product + "</td>";
rrtable += "<td class='rangereviewnumber'>" + item.py3.toLocaleString("en") + "</td>";
rrtable += "<td class='rangereviewnumber'>" + item.py2.toLocaleString("en") + "</td>";
rrtable += "<td class='rangereviewnumber'>" + item.py1.toLocaleString("en") + "</td>";
rrtable += "<td class='rangereviewnumber'>" + item.average.toLocaleString("en") + "</td>";
rrtable += "<td class='rangereviewnumber'>" + item.sales.toLocaleString("en") + "</td>";
rrtable += "<td class='rangereviewnumber'>" + item.share + "%</td>";
rrtable += "<td>✔</td>";
if(limit >= item.idnum){
rrtable += "<td>✔</td>";
rrtable += "<td class='checkboxcell' onClick=\"toggleCheckMark(this, '" + item.brand + "')\">✔</td>";
} else {
rrtable += "<td></td>";
rrtable += "<td class='checkboxcell' onClick=\"toggleCheckMark(this, '" + item.brand + "')\"></td>";
}
rrtable += "</tr>";
});
// increment iterations
i += 1;
$("#rangereviewtable").append(rrtable);
if(i == iterations){
var headimage = "<img src='http://url.com/images/oimage.png' width='63.5px' height='76px'>";
var table = $("#rangereviewtable").DataTable({
buttons: [{extend: 'excelHtml5', title: 'Range Review', text: 'Export to Excel'},
{extend: 'print', title: 'Range Review', message: headimage}],
});
//insert export to excel button into #rrbuttons div above actual table.
table.buttons().container().appendTo($('#rrbuttons'));
$("#rangereviewpanel").show();
$("#generatebutton").hide();
$("#loadbutton").hide();
$("#saveasbutton").show();
generateReviewSummary(summaryarray);
} else {
//do nothing not all iterations complete
}
},
error: function(jqXHR, textStatus, errorThrown) {
i+= 1;
console.log(textStatus, errorThrown);
}
});
});
}
Ich denke, vielleicht Versprechen könnte etwas für mich zu sehen sein. aber da ich wieder an meinen Tisch anschließe, bis alle Anrufe abgeschlossen sind und trotzdem zurückkommen, ist es kein Problem Async: false zu benutzen. Ich will nur nicht, dass synx xhr veraltet Fehler! Danke, dass Sie sich die Zeit genommen haben, zu antworten. –
@AdamCopley Ok, ich habe es verstanden. Sie möchten warten, bis alle Anfragen erledigt sind? Sie können async.each (Verknüpfung von Antwort) verwenden.Der letzte Rückruf wird bei jeder Anfrage ausgeführt. Und es ist viel besser als 'async: false', weil alle Anfragen immer noch parallel sind. –
Die Art, wie ich es habe, ist, dass ich möchte, dass die Callback-Funktion einige ihrer eigenen Sachen zur Antwort macht (Berechnungen mit Rangesize, Dropskus und Limit), bevor es an die Variable 'rrtable' angehängt wird. Wenn alle Aufrufe abgeschlossen sind, fügen Sie die rrtable-Zeichenfolge an die HTML-Tabelle an. –