JavaScript中CSV文件Schema校验问题及代码修复求助
CSV Schema校验JavaScript函数问题修复
需求说明
需要实现一个JavaScript函数,验证CSV文件是否符合指定Schema。测试CSV内容如下(第三行必填字段BU_NAME为空,应触发错误):
BU_NAME,BU_CONTACT,CONTEXT US_BU,John,FIN US_BU,Emily,SCM ,Eric,SCM UK_BU,Joe,SCM
第一段代码问题分析与修复
原代码问题
resolve(fileSet) { const validator = require('xsd-schema-validator'); let status = ''; if (fileSet.length > 0) { //Grab the first (and only) file let csvFile = fileSet[0]; //Check it's the correct type try { if (csvFile.type === 'text/csv') { alert('CSV FILE'); //Create a File reader and its onload callback let fileReader = new FileReader(); fileReader.onload = function (fileReadEvent) { let readCSVData = fileReadEvent.target.result; alert('result 11===>> ' + readCSVData); // resolve(readCSVData); }; fileReader.readAsText(csvFile); status = 200; } } catch (error) { alert('status ===>> ' + status+ ' error ==>> '+ error); return status = 500; } } return status; }
- 异步操作未处理:
FileReader.readAsText是异步操作,函数直接在调用后设置status=200并返回,完全未等待文件读取和校验完成。 - 无实际Schema校验逻辑:仅判断了文件类型,未对CSV内容做必填字段等校验,自然不会触发错误。
- catch块无效:仅能捕获同步代码错误,异步操作的错误无法进入该catch块。
修复后的代码
使用Promise处理异步流程,添加Schema校验逻辑:
function resolve(fileSet) { return new Promise((resolve, reject) => { if (fileSet.length === 0) { reject(500); return; } const csvFile = fileSet[0]; if (csvFile.type !== 'text/csv') { reject(500); return; } const fileReader = new FileReader(); fileReader.onload = function(fileReadEvent) { const readCSVData = fileReadEvent.target.result; const rows = readCSVData.split('\n').filter(row => row.trim() !== ''); // 过滤空行 // 校验表头(可根据实际Schema调整) const headers = rows[0].split(',').map(h => h.trim()); if (!headers.includes('BU_NAME') || !headers.includes('BU_CONTACT') || !headers.includes('CONTEXT')) { reject(500); return; } // 校验数据行 for (let i = 1; i < rows.length; i++) { const cells = rows[i].split(',').map(cell => cell.trim()); // 校验必填字段BU_NAME if (cells[0] === '') { reject(500); return; } // 可添加其他Schema校验规则,比如字段格式、长度等 } resolve(200); }; fileReader.onerror = function() { reject(500); }; fileReader.readAsText(csvFile); }); } // 使用示例 // resolve(fileSet).then(status => console.log(status)).catch(status => console.log(status));
第二段代码问题分析与修复
原代码问题
readAndProcess(file) { let status = 100; let flag = 0; let reader = new FileReader(); reader.onload = function (e) { let rows = e.target.result.split("\n"); for (let i = 1; i < rows.length; i++) { let cells = rows[i].split(","); if (cells.length < 2 || cells.length > 13) { flag = 1; break; } for (let j = 0; j < cells.length; j++) { if (cells[0] === "" || cells[11] === "" || cells[j] === "\r") { flag = 1; break; } } if (flag === 1) break; } if (flag){ window.alert("ERROR"); status = 500; } else{ window.alert("VALIDATED"); status = 200; } }; reader.readAsText(file); return status; }
- 异步导致状态赋值无效:
reader.readAsText是异步操作,函数立即返回初始值status=100,等onload执行时,函数已经完成返回,赋值的status无法被外部获取。 - 校验逻辑错误:
- 测试CSV仅3列,代码中判断
cells.length <2 || cells.length>13不符合实际需求,且cells[11]会导致数组越界。 cells[j] === "\r"的判断不合理,应通过trim()处理换行符。
- 测试CSV仅3列,代码中判断
修复后的代码
改用Promise处理异步,修正校验逻辑:
function readAndProcess(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = function(e) { const rows = e.target.result.split('\n').filter(row => row.trim() !== ''); if (rows.length <= 1) { // 无数据行 reject(500); return; } let isValid = true; // 校验数据行 for (let i = 1; i < rows.length; i++) { const cells = rows[i].split(',').map(cell => cell.trim()); // 校验列数(测试CSV为3列,可根据Schema调整) if (cells.length !== 3) { isValid = false; break; } // 校验必填字段BU_NAME(第一列) if (cells[0] === '') { isValid = false; break; } // 可添加其他校验规则,比如BU_CONTACT非空等 } if (isValid) { window.alert("VALIDATED"); resolve(200); } else { window.alert("ERROR"); reject(500); } }; reader.onerror = function() { window.alert("ERROR"); reject(500); }; reader.readAsText(file); }); } // 使用示例 // readAndProcess(file).then(status => console.log(status)).catch(status => console.log(status));
内容的提问来源于stack exchange,提问作者Balaganesh Mohanavel
相关产品推荐
相关产品推荐

