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

循环条件为真但For循环未执行,DOM文件面板填充失败求助

问题:Cordova File插件读取文件后无法填充DOM文件面板

问题现象

尝试用数组filesList填充文件面板,运行应用时:

  • 控制台显示filesList包含文件对象且长度大于0
  • DOM中的列表容器未添加任何元素
  • fillFilePanel函数内的循环代码没有执行(无对应日志输出)

相关代码

import { FILE_PANEL } from "../../app.js";

export function fillFilePanel(filesList) {
  console.log(filesList);
  for (let i = 0; i < filesList.length; i++) {
    let entries = filesList[i]
    if (entries.isDirectory == true) {
      FILE_PANEL.append(`<button id="F${entries.name}" type="button" class="list-group-item list-group-item-action" key="folder" data-toggle="#F${entries.name}Group">${entries.name}</button>
        <ul class="list-group" id="F${entries.name}Group">
        </ul>`);
      let parentDir = entries.name + '/';
      // showSubFolder(parentDir)
    }
    else {
      FILE_PANEL.append(`<button type="button" class="list-group-item list-group-item-action">${entries.name}</button>`);
    }
  }
}

MainFs.js

import { fillFilePanel } from "./ui/sideBar.js"
{
//...其他业务代码
let filesList = [];
listDir().then(val => (val.forEach((f) => { filesList.push(f); })));
  
fillFilePanel(filesList)
}

/**
 * 读取本地存储并填充侧边栏文件列表
 **/
export function listDir(url = '') {
  return new Promise(function(res, reject) {
    let path = cordova.file.externalRootDirectory + url
    window.resolveLocalFileSystemURL(path,
      function(fs) {
        const reader = fs.createReader();
        reader.readEntries(function(entries) {
          res(entries)
        }, (rej) => { return rej });
      }, (rej) => { return rej });
  });
}

控制台输出示例

[{"isFile":false,"isDirectory":true,"name":".face","fullPath":"/.face/","filesystem":"<FileSystem: sdcard>","nativeURL":"file:///storage/emulated/0/.face/"},{"isFile":false,"isDirectory":true,"name":".audio_param","fullPath":"/.audio_param/","filesystem":"<FileSystem: sdcard>","nativeURL":"file:///storage/emulated/0/.audio_param/"},{"isFile":false,"isDirectory":true,"name":"Music","fullPath":"/Music/","filesystem":"<FileSystem: sdcard>","nativeURL":"file:///storage/emulated/0/Music/"},{"isFile":false,"isDirec ...}]

问题原因

核心是异步执行顺序错误:

  • listDir()返回Promise,文件读取操作是异步的,then()回调会在文件读取完成后才执行
  • 调用listDir()后立刻执行fillFilePanel(filesList),此时filesList还是空数组,循环条件i < filesList.length不成立,循环代码完全没执行
  • 控制台后来看到的filesList有内容,是因为then()回调在fillFilePanel执行完之后才完成并填充了数组,但此时函数已经跑完了

解决办法

方案1:将填充操作放到Promise回调内

修改MainFs.js中的代码,确保在文件读取完成、数组填充后再调用fillFilePanel:

import { fillFilePanel } from "./ui/sideBar.js"
{
//...其他业务代码
let filesList = [];
listDir().then(val => {
  val.forEach((f) => { filesList.push(f); });
  fillFilePanel(filesList); // 数组填充完成后再调用
});
}

方案2:使用async/await简化异步逻辑

用async/await替代Promise回调,代码更直观:

import { fillFilePanel } from "./ui/sideBar.js"

// 用自执行async函数包裹
(async function() {
//...其他业务代码
let filesList = await listDir(); // 等待文件读取完成,直接获取结果
fillFilePanel(filesList);
})();

额外检查点

  • 确认FILE_PANEL是正确获取的DOM元素,可以在fillFilePanel开头加console.log(FILE_PANEL)验证是否为有效DOM节点
  • 循环内添加console.log(entries),修复异步问题后可以确认循环正常执行

内容的提问来源于stack exchange,提问作者John Delvin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:55:28