繁体   English   中英

当所有 Ajax 调用完成时调用 JavaScript 函数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM