Node.js中forEach循环推送编辑后数据到数组仍返回原始数据问题
问题核心原因
和异步逻辑没有关系,是代码的替换逻辑本身存在错误:
- 每遍历CSV单行数据中的一个键值对,就重新读取一次原始
index.html文件,将整份文件的所有行追加到newCode数组。遍历完一行的N个键后,newCode里会存入N份重复的HTML内容,每份仅替换了单个占位符,完全不是逐次累积替换所有占位符的效果。 - 占位符匹配规则写为
{(字段名)}格式,和常规的{字段名}/{{字段名}}占位符写法不匹配,会直接导致匹配失败,看起来就像循环没有执行替换操作。 - 使用字符串
replace方法时没有开启全局匹配,同一行如果出现多个相同占位符,只会替换第一个。 - 开头声明的
matrix数组全程未使用,单条CSV行处理完打印后就被销毁,没有做结果归集。
修复方案
- 将HTML模板的读取操作放到循环外,整个流程只需要读一次模板文件,避免重复IO和内容重复追加的问题
- 处理单条CSV行数据时,基于原始模板的拷贝做替换,所有键值对都替换完成后再把结果存入最终结果数组
- 按HTML中实际的占位符格式调整匹配规则,需要替换同个占位符多次出现的场景时,用正则开启全局匹配
- 所有CSV行处理完成后统一输出或写入结果文件,避免数据丢失
修复后的可运行代码:
import * as fs from 'node:fs'; import { parse } from 'csv-parse'; // 仅读取一次HTML模板,放在所有循环外 const htmlTemplate = fs.readFileSync('index.html', 'utf8').split('\n'); fs.readFile('test.csv', 'utf8', (err, csvData) => { if (err) throw err; const finalResult = []; parse(csvData, {columns: true, trim: true}, (parseErr, rows) => { if (parseErr) throw parseErr; rows.forEach(row => { // 基于原始模板拷贝一份做替换,不修改原模板内容 const processedLines = [...htmlTemplate]; for (const [key, value] of Object.entries(row)) { // 按实际占位符格式调整正则,示例为匹配{key}格式的全局替换 // 如果占位符是{{key}}格式,把正则改成 new RegExp(`\\{\\{${key}\\}\\}`, 'g') const placeholderReg = new RegExp(`\\{${key}\\}`, 'g'); // 逐行替换当前key对应的所有占位符 for (let i = 0; i < processedLines.length; i++) { processedLines[i] = processedLines[i].replace(placeholderReg, value); } } finalResult.push(processedLines.join('\n')); }); // 所有行处理完成后打印结果 console.log('处理完成,结果列表:', finalResult); // 可选:将结果写入输出文件 fs.writeFileSync('output.html', finalResult.join('\n\n<!-- 不同CSV行生成内容分隔线 -->\n')); }) })
内容的提问来源于stack exchange,提问作者bjm
相关产品推荐
相关产品推荐

