You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript全局数组在事件间数据丢失问题求助

问题根源与解决方案

1. 核心问题:变量重声明覆盖外层作用域

在$('#fileInput').on('change')事件处理函数内部,你重新声明了var fileListProperty = [];,这会创建一个局部变量,完全覆盖了$(document).ready作用域下的同名数组。也就是说,你在change事件里填充的是这个局部数组,而外层的目标数组始终是空的,所以点击提交按钮时访问的自然是空数组。

修复方法:删除change事件内部的var fileListProperty = [];,直接清空外层作用域的数组(避免多次选择文件时数据累积):

// 在change事件内,替换原来的var声明
fileListProperty = []; // 直接操作外层数组,不要加var

2. 其他潜在问题修复

(1) Promise参数传递错误

Promise的resolve和reject只能传递一个参数,你现在传了两个参数resolve(file.name, index),第二个参数会被直接忽略。需要把参数包装成对象传递:

// 修正resolve/reject调用
resolve({ fileName: file.name, index: index });
reject({ fileName: file.name, index: index });

// 对应then回调也要修改
onLoadPromise.then(
  (result) => {
    const { fileName, index: zeIndex } = result;
    // 后续逻辑不变
  },
  (error) => {
    const { fileName, index: zeIndex } = error;
    // 后续逻辑不变
  }
)

(2) 变量拼写错误

在非PP7文件的处理分支里,你写的是nbFile++,但前面声明的计数变量是nbFiles,这会导致计数错误,修改为:

nbFiles++;

(3) 提交事件重复绑定问题

每次点击提交按钮时,你都会重新绑定$('#pp7Form').submit事件,这会导致事件被多次绑定,后续提交会触发多次回调。应该把提交事件绑定移到$(document).ready的顶层:

// 在ready顶层绑定一次提交事件
$(document).ready(() => {
  // ...其他代码
  $('#pp7Form').submit((evt) => {
    if ($("#fileInput").prop("files").length === 0) {
      evt.preventDefault();
      return;
    }
    $("#pp7Form").ajaxSubmit();
    return false;
  });

  // 提交按钮的click事件只处理进度查询逻辑
  $("#btnSubmit").on('click', () => {
    if ($("#fileInput").prop("files").length === 0) return;
    // 进度查询逻辑...
  });
});

(4) 异步轮询的死循环问题

你用while (nbFilecompleted < nbValidFile)来循环查询进度,但$.post是异步操作,while会在异步请求返回前无限执行,直接导致浏览器卡死。改用递归+setTimeout实现轮询:

// 替换原来的while循环
var nbValidFile = fileListProperty.filter(element => element.valid).length;
var nbFilecompleted = 0;

const checkProgress = () => {
  if (nbFilecompleted >= nbValidFile) return;
  
  let hasPending = false;
  fileListProperty.forEach((file, idx) => {
    if (file.valid && file.pctConversion < 100) {
      hasPending = true;
      $.post('https://ol-portal-dev-nr.ca.objectiflune.com/getStat', {
        UUID: $("#uuid").val(),
        fileID: file.fileIndex
      }, (data, status, xhr) => {
        if (status === 'success') {
          const percentage = JSON.parse(data).percentage;
          file.pctConversion = percentage;
          if (percentage === 100) nbFilecompleted++;
        } else {
          alert('An error has occurred, please contact jhamel@uplandsoftware.com');
        }
      });
    }
  });
  
  if (hasPending) setTimeout(checkProgress, 500);
};

checkProgress(); // 启动轮询

最终修复后的关键代码片段

$(document).ready(() => {
  var fileListProperty = [];

  $("#loaderContainer").hide();

  $("#browseBtn").on('click', () => {
    $('#btnSubmit').addClass("btnSubmitDisabled");
    $("#formList").empty();
    $('#fileInput').click();
  });

  $('#fileInput').on('change', () => {
    $("#loaderContainer").show();
    var files = $("#fileInput").prop("files");
    var fileListValid = false;
    fileListProperty = []; // 清空外层数组
    var nbFiles = 0;
    const dt = new DataTransfer();

    Array.from(files).forEach((file, index) => {
      if (file.name.indexOf(".pp7") >= 0) {
        let onLoadPromise = new Promise((resolve, reject) => {
          let reader = new FileReader();
          reader.onloadend = (evt) => {
            let fileContent = evt.target.result;
            if (fileContent.substr(0, 2) === "PK") {
              resolve({ fileName: file.name, index: index });
            } else {
              reject({ fileName: file.name, index: index });
            }
          }
          reader.readAsText(file);
        });

        onLoadPromise.then(
          (result) => {
            const { fileName, index: zeIndex } = result;
            dt.items.add(file);
            fileListProperty.push({
              fileIndex: zeIndex,
              fileName: file.name,
              valid: true,
              message: "Valid PP7 file.",
              pctConversion: 0
            });
          },
          (error) => {
            const { fileName, index: zeIndex } = error;
            fileListProperty.push({
              fileIndex: zeIndex,
              fileName: file.name,
              valid: false,
              message: fileName + " isn't a valid PP7 file. Cannot be converted.",
              pctConversion: 0
            });
          }
        ).finally(() => {
          nbFiles++;
          if (nbFiles === files.length) DisplayFileList();
        });
      } else {
        fileListProperty.push({
          fileIndex: index,
          fileName: file.name,
          valid: false,
          message: file.name + " isn't a valid PP7 file. Cannot be converted.",
          pctConversion: 0
        });
        nbFiles++;
        if (nbFiles === files.length) DisplayFileList();
      }
    });

    var DisplayFileList = () => {
      fileListValid = false;
      fileListProperty.forEach((propJSON) => {
        if (propJSON.valid) fileListValid = true;
      });

      $("#fileInput").prop("files", dt.files);

      $("#loaderContainer").delay(1500).hide(0, () => {
        BuildFormList();
        if (fileListValid) {
          $('#btnSubmit').removeClass("btnSubmitDisabled");
        }
      });
    }

    var BuildFormList = () => {
      $("#formList").empty();
      fileListProperty.forEach((listProperty) => {
        $("#formList").append(
          `<div class="fileContainer" idx="${listProperty.fileIndex}">` +
          `    <div class="fileName">${listProperty.fileName}</div>` +
          `    <div class="fileMessage ${listProperty.valid ? 'valid' : 'error'}">${listProperty.message}</div>` +
          `</div >`);
      });
    }
  });

  $('#pp7Form').submit((evt) => {
    if ($("#fileInput").prop("files").length === 0) {
      evt.preventDefault();
      return;
    }
    $("#pp7Form").ajaxSubmit();
    return false;
  });

  $("#btnSubmit").on('click', () => {
    if ($("#fileInput").prop("files").length === 0) return;

    var nbFilecompleted = 0;
    var nbValidFile = fileListProperty.filter(element => element.valid).length;

    const checkProgress = () => {
      if (nbFilecompleted >= nbValidFile) return;
      let hasPending = false;
      fileListProperty.forEach((file, idx) => {
        if (file.valid && file.pctConversion < 100) {
          hasPending = true;
          $.post('https://ol-portal-dev-nr.ca.objectiflune.com/getStat', {
            UUID: $("#uuid").val(),
            fileID: file.fileIndex
          }, (data, status, xhr) => {
            if (status === 'success') {
              const percentage = JSON.parse(data).percentage;
              file.pctConversion = percentage;
              if (percentage === 100) nbFilecompleted++;
            } else {
              alert('An error has occurred, please contact jhamel@uplandsoftware.com');
            }
          });
        }
      });
      if (hasPending) setTimeout(checkProgress, 500);
    };

    checkProgress();
  });
});

内容的提问来源于stack exchange,提问作者Jean-Cédric Hamel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 11:45:00