多目录单音乐文件提取代码异常:仅第二个目录返回数据
问题分析与修复方案
首先,咱们来拆解下你遇到的核心问题:配置多个目录时,第一个目录的结果完全丢失,只有第二个目录的内容正常返回。这大概率是结果数组的复用逻辑出了问题,再结合代码里的细节,咱们一步步修复:
核心问题:数组参数的传递错误
你的findSongs函数里写了musics = musics || [],但如果调用时没有主动传入同一个数组,每次调用都会创建全新的空数组。比如如果你的调用代码是这样的:
let finalMusics = []; for (const dir of config.dirs) { // 错误:每次调用都生成新数组,直接覆盖之前的结果 finalMusics = await findSongs(dir); }
那第一个目录处理出来的数组会被第二个目录的新数组完全覆盖,自然看不到第一个目录的内容。
分步修复方案
确保调用时复用同一个结果数组
修改调用逻辑,主动将同一个数组传入每一次findSongs调用,让所有目录的结果都累积到这个数组里:const config = require('./config.json'); let allMusics = []; async function processAllDirs() { for (const dir of config.dirs) { await findSongs(dir, false, allMusics); // 传入同一个数组,累积结果 } console.log(allMusics); // 现在两个目录的结果都会在这里 } processAllDirs();修复路径拼接的跨平台兼容性问题
你用${baseDir}/${file}拼接路径在Windows系统下可能会出现识别错误,建议改用Node.js内置的path.join方法,它会自动适配不同系统的路径分隔符:const path = require('path'); // ... let musicPath = path.join(baseDir, file);替换同步文件操作为异步版本
当前代码里用了fs.lstatSync同步方法,在异步函数里建议改用异步的fs.promises.lstat,避免阻塞事件循环:let stat = await fs.promises.lstat(musicPath);完善函数返回值与错误处理(可选但推荐)
为了让函数逻辑更健壮,可以让findSongs返回处理后的数组,同时增加子级错误捕获,避免单个文件/目录出错导致整个目录处理中断:var findSongs = async function (baseDir, isDir = false, musics) { try { musics = musics || []; var files = await getDirFiles(baseDir); for (let i = 0; i < files.length; i++) { try { let file = files[i]; let musicPath = path.join(baseDir, file); let stat = await fs.promises.lstat(musicPath); if (stat.isDirectory()) { await findSongs(musicPath, true, musics); } else { let meta = await getMusicMeta(musicPath); if (meta) { musics.push(meta); } if (isDir) { break; // 子目录只取第一个符合要求的文件,符合你的需求 } } } catch (subErr) { console.error(`处理文件/目录失败: ${file}`, subErr); } } return musics; // 返回结果数组,方便单独调用单个目录时获取结果 } catch (err) { console.error(`处理目录失败: ${baseDir}`, err); return musics; // 即使目录处理出错,也返回已收集的部分结果 } };
验证效果
现在运行processAllDirs函数后,allMusics数组会正确累积两个目录下的结果:
- 根目录(
isDir=false)会遍历所有文件和子目录 - 每个子目录(
isDir=true)只会提取第一个符合要求的歌曲 - 不会再出现第一个目录结果丢失的情况
内容的提问来源于stack exchange,提问作者moein rahimi
相关产品推荐
相关产品推荐

