为什么我的Node.js+Electron函数中if语句仅第二次触发生效?
问题分析与解决方案
核心问题原因
你代码里的关键bug是第一次点击时,自定义的console.log函数根本没执行:
- 第一次点击按钮,执行
console.log(row)时用的还是浏览器原生的console.log,之后才重写了console.log函数,所以DOM更新、按钮隐藏这些逻辑完全没触发。 - 第二次点击时,
console.log已经被改成你自定义的版本了,这时候执行console.log(row)才会触发页面上的操作。
另外还有几个额外问题:每次调用函数都重新加载fs和csv-parse模块、找到匹配行后还会继续读取整个CSV文件、DOM拼接写法冗余。
修正后的代码
// 把模块require移到函数外面,避免每次调用重复加载 const fs = require("fs"); const { parse } = require("csv-parse"); function ReadSerials() { const serialnumber = document.getElementById("serialnumberinput").value.trim(); const inputbg = document.getElementById("serialnumberinput"); const logger = document.getElementById('serialselect'); const submitBtn = document.getElementById("serialsubmit"); // 先重置之前的状态(比如上次搜索的结果、输入框样式) logger.innerHTML = ''; submitBtn.style.visibility = "visible"; inputbg.style.backgroundColor = ""; if (!serialnumber) { inputbg.style.backgroundColor = "#ff6b6b33"; return; } const stream = fs.createReadStream("./SER5YEAR.csv") .pipe(parse({ delimiter: ",", from_line: 1 })) .on("data", function(row) { if (row.includes(serialnumber)) { // 直接执行DOM更新,不要再重写console.log const resultHtml = ` <td class="serialresult">${row[1]}</td> <td class="serialresult">${row[2]}</td> <td class="serialresult">${row[3]}</td> <td class="serialresult">${row[4]}</td> <td class="serialresult">${row[5]}</td> <td class="serialresult">${row[6]}</td> `; logger.innerHTML += resultHtml; submitBtn.style.visibility = "hidden"; inputbg.style.backgroundColor = "#63c63c33"; // 找到匹配项后立即停止读取文件,节省资源 stream.destroy(); } }) .on("end", function() { // 文件读完都没找到匹配项,给用户反馈 if (submitBtn.style.visibility !== "hidden") { inputbg.style.backgroundColor = "#ff6b6b33"; logger.innerHTML = '<td colspan="6" class="serialresult">未找到该序列号</td>'; } }) .on("error", function(err) { console.error("读取CSV文件出错:", err); inputbg.style.backgroundColor = "#ff6b6b33"; logger.innerHTML = '<td colspan="6" class="serialresult">文件读取失败</td>'; }); }
关键修改点说明
- 移除console.log重写:直接在匹配到行时执行DOM操作,这是解决点击两次问题的核心。
- 模块预加载:把
require移到函数外部,避免每次调用函数都重新加载模块,提升性能。 - 状态重置:每次搜索前清空之前的结果、恢复按钮可见性、重置输入框样式,避免上次搜索的残留影响。
- 停止文件流:找到匹配项后调用
stream.destroy()终止文件读取,不用再读剩下的内容。 - 添加错误处理:监听
end和error事件,处理未找到序列号、文件读取失败的情况,给用户明确反馈。 - 简化HTML拼接:用模板字符串替代重复的
innerHTML +=,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者CB700
相关产品推荐
相关产品推荐

