You need to enable JavaScript to run this app. discord.js扩展系统开发:for循环读取JSON模块报mod.commands不可迭代问题
优惠活动
大模型
产品
解决方案
定价
更多

discord.js扩展系统开发:for循环读取JSON模块报mod.commands不可迭代问题

报错根因

mod.commands isn't iterable的本质原因是:mod.commands是键值对形式的普通JS对象(结构为{命令名: 命令文件地址}),而for...of循环仅支持遍历数组、Map、Set等原生可迭代对象,无法直接遍历普通对象的属性,因此触发类型错误。
除此之外原代码还存在几处关联逻辑bug,会在遍历修正后继续触发报错:

  • 变量引用错误:循环中拿到的module是fs.readdirSync返回的文件名字符串(如user_module.json),不是require解析后的模块对象,原代码写的module.name根本无法取到JSON里定义的模块名
  • 数据库判断逻辑错误:原代码只在数据库存单个模块名,一旦命中判断就直接return中断整个循环,会跳过后续所有未处理的模块
  • 未定义变量引用:download方法调用时传入了未定义的error变量作为回调
可直接运行的修正方案
  1. 使用Object.entries()将普通对象转为可迭代的键值对数组,适配for...of遍历
  2. 修正模块名的变量引用,用解析后的模块对象mod取name字段
  3. 调整已解析模块的存储逻辑,用数组存储所有已处理的模块名,遍历过程中跳过已解析项
  4. 补全download方法的错误回调,避免引用未定义变量
修正后的loadExt函数代码
function loadExt(){
    const moduleFiles = fs.readdirSync(`./modules`).filter(file => file.endsWith('.json'));
    // 初始化读取数据库中已解析的模块列表,没有则默认空数组
    const parsedModules = db.get('parsedModules') || [];
    
    for (const moduleFileName of moduleFiles){
        // 跳过已经解析过的模块
        if (parsedModules.includes(moduleFileName)) continue;
        
        // 解析模块JSON内容
        const mod = require(`./modules/${moduleFileName}`)
        // 遍历commands对象的[命令名, 命令地址]键值对
        for (const [commandName, commandUrl] of Object.entries(mod.commands)){
            download(
                commandUrl, 
                `./commands/ext/${mod.name}/${commandName}.js`, 
                (err) => {
                    if (err) console.error(`模块 ${mod.name} 的命令 ${commandName} 加载失败:`, err);
                }
            );
        }
        // 将处理完成的模块加入已解析列表,写回数据库
        parsedModules.push(moduleFileName);
        db.set('parsedModules', parsedModules);
    }
}

内容的提问来源于stack exchange,提问作者Anden Wieseler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 13:15:01