FileReader onprogress始终显示100%:CSV文件解析进度展示异常求助
Hey there, let's break down why your progress isn't updating properly and how to get real-time progress for your CSV parsing.
Why onprogress Only Shows 100%?
The issue here is how readAsText() works: it loads the entire file into memory in one go before firing the onload event. For local files (even 40MB ones), modern storage is fast enough that the browser reads the whole file almost instantly. That means the onprogress event either fires once at 100% or doesn't fire at all—there's no time to catch intermediate states.
To get actual incremental progress, you need to read the file in chunks and parse those chunks as they're loaded, instead of waiting for the whole file to load first.
Solution: Chunked Reading + Streaming CSV Parsing
Here's a revised TypeScript implementation that uses Blob.slice() to read the file in chunks, paired with csv-parse's streaming API to process data incrementally. This will give you real progress updates as the file is read and parsed:
async function parseCSVWithProgress(file: File) { const chunkSize = 1024 * 1024; // 1MB chunks - adjust based on your needs const totalFileSize = file.size; let bytesRead = 0; let parser: ReturnType<typeof csvParse>; // Initialize the csv-parse stream with your config (add header: true if needed) const initParser = () => { parser = csvParse({ // Example config: header: true, skip_empty_lines: true }, (err, parsedRows) => { if (err) throw new Error(`CSV parsing error: ${err.message}`); // Add parsed rows to your data array this.jsonData.push(...parsedRows); }); }; initParser(); while (bytesRead < totalFileSize) { const chunkEnd = Math.min(bytesRead + chunkSize, totalFileSize); const fileChunk = file.slice(bytesRead, chunkEnd); await new Promise<void>((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { // Feed the chunk to the parser parser.write(e.target?.result as string); // Update progress bytesRead = chunkEnd; const progress = Math.round((bytesRead / totalFileSize) * 100); console.log(`Current progress: ${progress}%`); resolve(); }; reader.onerror = () => { reject(new Error(`Failed to read chunk: ${reader.error?.message}`)); }; reader.readAsText(fileChunk); }); } // Finalize the parser once all chunks are processed parser.end(); console.log("CSV parsing complete!"); } // Call this function with your file: // parseCSVWithProgress(this.file);
Key Improvements:
- Chunked File Reading:
Blob.slice()splits the file into manageable pieces, so we never load the entire file into memory at once (great for large files!). - Streaming Parsing: csv-parse's
write()method lets us process each chunk as it's read, so you get data incrementally instead of waiting for the whole file. - Accurate Progress Tracking: We calculate progress based on how many bytes we've actually read, so you'll see updates from 0% to 100% as chunks load.
Quick Tips:
- Adjust
chunkSizebased on your use case: smaller chunks mean more frequent progress updates, but slightly more overhead. 1MB is a good starting point. - If your CSV has headers, add
header: trueto the csv-parse config to avoid treating the first row as data. - Add error handling for parsing issues (like malformed CSV) in the parser's callback to make your code more robust.
内容的提问来源于stack exchange,提问作者VedhaR

