【问题标题】:Call JavaScript function when all Ajax calls finished当所有 Ajax 调用完成时调用 JavaScript 函数
【发布时间】:2020-07-12 00:09:09
【问题描述】:

需要帮助处理一些无法按预期工作的 JavaScript 代码。

应用程序通过 Ajax 调用将文件名发送到服务器以进行处理,但我想告诉数据库当前导入已完成,当它们全部完成时。我遇到的问题是在任何 ajax 调用运行之前使用状态更新数据库的代码。

我已经准备好在网络上的许多区域,您可以创建一个承诺数组来跟踪它,但 JavaScript 老实说是我的一个弱点,我不知道如何去实现它。

以下是我当前的代码 sn-ps:

循环文件名的函数:

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();
}

这两个函数都源自网络上的其他教程,但我不完全确定它们是否按照我最初的意图进行,因为由于另一个要求,我才刚刚开始尝试跟踪完成状态。

任何帮助都会很棒。另外,如果我可以包含任何其他细节以使这个问题对其他人更好一些,请告诉我,我会相应地更新。

更新 我尝试更新代码以使用 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();
            }
        });
    })
}

【问题讨论】:

    标签: javascript ajax


    【解决方案1】:

    您似乎在使用 jQuery,所以我尝试提供一个基于 jQuery 的解决方案,而无需原生承诺。我认为你应该使用原生 Promise 和内置的 fetch() 函数,而不是单独使用 jQuery 或 jQuery。

    关键是使用$.map()返回一组promise,然后使用$.when()等待所有的promise。此外,return 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;
            }
        });
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-31
      • 2014-06-10
      相关资源
      最近更新 更多