我尝试过研究这个问题,我知道这个错误的发生是因为太多的ajax调用导致浏览器无法处理它。但是我认为解决方案是个案。让我试着解释这段代码是如何工作的
首先我选择一个csv文件(8000行),然后我将它上传到数据库,调用函数就像这样工作。
$(document).on("click", "#btn-group-agent-upload", function () {
var reader = new FileReader();
updateUploadPercentage(0);
var file = $("#group-agent-file").prop("files")[0];
reader.readAsText(file, 'UTF-8');
reader.onload = Insert_Bulk_Agent;
});
并执行此
的函数Insert_Bulk_Agent
function Insert_Bulk_Agent(event) {
var result = event.target.result;
var data = $.csv.toObjects(result);
var length = data.length;
var count = 0;
var arrayCollection = [];
var tbody = $("#error-list").find("tbody");
if (length > 0) {
$.each(data, function (key, val) {
if(val.AgentStatus == "" || val.BirthDate == "" || val.CSP == "" || val.Classification == "" || val.ContactNumber == "" ||
val.EmailAddress == "" || val.FirstName == "" || val.LastName == "" || val.MiddleName == "" || val.LiveDate == "" || val.Program == "") {
$.ajax({
success: function () {
//console.log('ok');
$(tbody).append("<tr><td>" + val.FirstName + ' ' + val.MiddleName + ' ' + val.LastName + "</td>" +
"<td>" + val.Tool + "</td></tr>");
arrayCollection.push(val);
count = count + 1;
var percentageCompleted = count / length * 100;
updateUploadPercentage(parseInt(percentageCompleted));
}
});
} else {
$.ajax({
xhr: function () {
var xhr = $.ajaxSettings.xhr();
xhr.upload.onprogress = function (evt) {
count = count + 1;
var percentageCompleted = count / length * 100;
updateUploadPercentage(parseInt(percentageCompleted));
};
return xhr;
},
type: "POST",
url: "IROA_StoredProcedures.asmx/Insert_Bulk_Agent",
data: JSON.stringify(val),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
},
error: function (XMLHttpRequest) {
count = count + 1;
var percentageCompleted = count / length * 100;
updateUploadPercentage(parseInt(percentageCompleted));
console.log(XMLHttpRequest);
console.log(JSON.stringify(val));
}
});
}
});
}
else {
alert("The selected file is empty");
}
Update_uam();
}
第一
函数循环遍历每一行,并评估所需字段是否不是null
或""
值。如果是函数,则在html
表中添加一行。如果它有值,它将调用一个将值插入数据库的ajax。现在问题是由于多次AJAX
调用而出现问题。我该如何处理这个错误?
第二
还有一个函数可以在这里调用update_uam
是否确保此函数将在所有Insert_Bulk_Agent
进程之后执行?
答案 0 :(得分:2)
首先,这是我写的一个“多个”队列(但从未在生产中测试过,所以感谢你作为豚鼠:p)
这允许你有一个单独的“队列”来添加Promise,它们最终会在max
并行队列中 - 这对于限制并发ajax请求的数量是完美的。顺便说一下$.ajax
,返回一个Promise
现在,这是原始的,因为其中一个队列中的任何错误都将暂停该队列,因此可能需要更多才能正常使用
const multiQueue = max => {
max = (isNaN(max) || max < 1) ? 1 : max;
const q = new Array(max).fill(0).map(() => Promise.resolve());
let index = 0;
const add = (cb, ...args) => {
index = (index + 1) % max;
return (q[index] = q[index].then(() => cb(...args)));
};
return add;
};
我只是快速思考,可能
return (q[index] = q[index].then(() => cb(...args)
.then(data => ({data}))
.catch(error => ({error}))
);
可能使队列不那么脆弱,请注意所有承诺将解析为
{data: whatever the resolved result was}
或{error: whatever the rejection reason was}
您的代码更改很少
Promise.all(data.map((val, key) => {
// inside the map function
})).then(Update_uam);
这将等到所有Promises(ajax)完成,然后调用Update_uam
在地图函数中
return queue(() => $.ajax({
// ajax request
}));
返回$.ajax
返回的已添加到队列中的承诺
所以,整个代码是:
var queue = multiQueue(6); // most browsers I think limit to 6 simultaneous AJAX anyway
function Insert_Bulk_Agent(event) {
var result = event.target.result;
var data = $.csv.toObjects(result);
var length = data.length;
var count = 0;
var arrayCollection = [];
var tbody = $("#error-list").find("tbody");
if (length > 0) {
Promise.all(data.map((val, key) => {
if (val.AgentStatus == "" || val.BirthDate == "" || val.CSP == "" || val.Classification == "" || val.ContactNumber == "" ||
val.EmailAddress == "" || val.FirstName == "" || val.LastName == "" || val.MiddleName == "" || val.LiveDate == "" || val.Program == "") {
return queue(() => $.ajax({
success: function() {
//console.log('ok');
$(tbody).append("<tr><td>" + val.FirstName + ' ' + val.MiddleName + ' ' + val.LastName + "</td>" +
"<td>" + val.Tool + "</td></tr>");
arrayCollection.push(val);
count = count + 1;
var percentageCompleted = count / length * 100;
updateUploadPercentage(parseInt(percentageCompleted));
}
}));
} else {
return queue(() => $.ajax({
xhr: function() {
var xhr = $.ajaxSettings.xhr();
xhr.upload.onprogress = function(evt) {
count = count + 1;
var percentageCompleted = count / length * 100;
updateUploadPercentage(parseInt(percentageCompleted));
};
return xhr;
},
type: "POST",
url: "IROA_StoredProcedures.asmx/Insert_Bulk_Agent",
data: JSON.stringify(val),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function() {
},
error: function(XMLHttpRequest) {
count = count + 1;
var percentageCompleted = count / length * 100;
updateUploadPercentage(parseInt(percentageCompleted));
console.log(XMLHttpRequest);
console.log(JSON.stringify(val));
}
}));
}
})).then(Update_uam);
} else {
alert("The selected file is empty");
Update_uam();
}
}