[英]Detect when all JQuery / JavaScript / Ajax calls are finished
[英]Call JavaScript function when all Ajax calls finished
需要一些无法按预期工作的 JavaScript 代码的帮助。
应用程序通过 Ajax 调用将文件名发送到服务器进行处理,但我想在它们全部完成后告诉数据库当前导入已完成。 我遇到的问题是在任何 ajax 调用运行之前使用状态运行更新数据库的代码。
我已经准备好在网络上的许多领域,你可以创建一个承诺数组来跟踪它,但老实说 JavaScript 是我的一个弱点,我不知道我会如何去实现它。
以下是我当前的代码片段:
循环遍历文件名的函数:
function importFiles() {
serverImporterInit();
let files = getFiles();
if (files) {
showImportProgressModal(files);
let looper = $.Deferred().resolve();
$.when.apply($, $.map(files, function (file, index) {
let fileStatusElement = document.getElementById('file-' + index + '-status');
let fileErrorElement = document.getElementById('file-' + index + '-error');
looper = looper.then(function () {
setTimeout(function () {
return import_file_request(file, fileStatusElement, fileErrorElement);
}, 2000);
});
return looper;
})).then(function () {
});
}
}
ajax调用服务器:
function import_file_request(file, element, errorElement) {
let deferred = $.Deferred();
fileImportStatusInProgress(element);
$.ajax({
type: 'POST',
url: '/importer/manual_import',
data: {'file': file.toString()},
success: function(data) {
fileImportStatusSuccess(element);
deferred.resolve(data);
},
error: function (error) {
fileImportStatusFailed(error, element, errorElement);
deferred.reject(error);
}
});
return deferred.promise();
}
这两个函数都是从网络上的其他教程派生出来的,但我不完全确定它们是否做过我最初打算做的,因为我只是因为另一个要求才开始尝试跟踪完成状态。
任何帮助都会很棒。 另外,如果我可以包含任何其他细节以使这个问题对其他人更好一点,请告诉我,我会相应地更新。
更新我尝试更新代码以使用承诺数组,但仍然没有运气。
文件循环:
const importFiles = async (files) => {
serverImporterInit()
const filesLength = files.length
showImportProgressModal(files);
for (let i = 0; i < filesLength; i++) {
const requests = files.map((file) => {
let fileStatusElement = document.getElementById('file-' + i + '-status');
let fileErrorElement = document.getElementById('file-' + i + '-error');
return import_file_request(file, fileStatusElement, fileErrorElement) // Async function to import file
.then(console.log(file + " successfully imported"))
.catch(e => console.log('Error'))
})
await Promise.all(requests)
.then(serverImporterClose())
.catch(e => console.log(''))
}
}
要切断的文件导入请求:
function import_file_request(file, element, errorElement) {
fileImportStatusInProgress(element);
return new Promise((resolve, reject) => {
$.ajax({
type: 'POST',
url: '/importer/manual_import',
data: {'file': file.toString()},
success: function(data) {
fileImportStatusSuccess(element);
resolve();
},
error: function (error) {
fileImportStatusFailed(error, element, errorElement);
reject();
}
});
})
}
您似乎在使用 jQuery,所以我尝试提供一个没有本机承诺的基于 jQuery 的解决方案。 我认为您应该将本机承诺与内置fetch()
函数结合使用,而不要单独使用 jQuery 或 jQuery。
关键是使用$.map()
返回一组承诺,然后使用$.when()
等待所有承诺。 此外,返回jQuery 承诺总是很重要的。
function importFiles() {
var files = getFiles();
if (files) {
showImportProgressModal(files);
serverImporterInit();
var promises = $.map(files, function(file, index) {
let fileStatusElement = document.getElementById('file-' + index + '-status');
let fileErrorElement = document.getElementById('file-' + index + '-error');
return import_file_request(file, fileStatusElement, fileErrorElement)
})
$.when.apply($, promises).then(function(results) {
serverImporterClose();
results.forEach(function(result) {
if (result) {
console.log("yay, success");
}
else {
console.log("failed");
}
})
hideImportProgressModal(files);
});
}
}
function import_file_request(file, element, errorElement) {
fileImportStatusInProgress(element);
// MUST return the promise here
return $.ajax({
type: 'POST',
url: '/importer/manual_import',
data: {'file': file.toString()},
success: function(data) {
fileImportStatusSuccess(element);
return true;
},
error: function (error) {
fileImportStatusFailed(error, element, errorElement);
return false;
}
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.