Node.js中如何在line-reader的eachLine方法中终止读文件及全流程?
使用line-reader逐行读取文件时的提前终止方案
问题描述
需要实现逐行读取文件的逻辑,在匹配到指定内容节点时立刻终止整个读取流程,避免多余的IO开销,同时保证函数可以正常重复调用。
原始封装代码如下:
const lineReader = require('line-reader'); var truevar = false; async function readLines(filename, processLine) { return new Promise((resolve, reject) => { lineReader.eachLine(filename, (line, last, callback) => { if (!callback) throw new Error('panic'); if (truevar) { // 我需要在此处终止并结束整个函数 } else { processLine(line) .then(() => last ? resolve() : callback()) .catch(reject); }; }); }) };
函数调用方式:
await readLines('somefile.txt', async (line) => { await delay(1000) // 1秒 other_function(line); });
遇到的问题:查阅line-reader文档未找到明确的终止方案,直接使用break等方式粗暴终止会导致进程卡住,函数后续无法重复调用,必须重启程序才能恢复正常。
解决方案
line-reader的eachLine方法本身支持终止逻辑:在逐行回调中返回false即可立刻终止文件读取操作。配合标记位的合理使用就能实现需求,修正后的代码如下:
const lineReader = require('line-reader'); async function readLines(filename, processLine) { // 标记位移到函数内部,每次调用自动重置为false,避免全局污染 let stopReading = false; return new Promise((resolve, reject) => { lineReader.eachLine(filename, (line, last, callback) => { if (!callback) throw new Error('panic'); if (stopReading) { // 返回false终止读取 return false; } // 给处理函数注入终止方法,业务层需要终止时调用即可 processLine(line, () => { stopReading = true; }) .then(() => { // 读取到最后一行或者触发终止,都结束Promise if (last || stopReading) { resolve(); return; } callback(); }) .catch(reject); }); }) };
调用示例:
await readLines('somefile.txt', async (line, stop) => { await delay(1000); // 匹配到终止节点时调用stop方法 if (line === '指定的终止节点内容') { stop(); return; } other_function(line); });
之前遇到的无法重复调用的问题,核心原因是原始代码的终止标记truevar定义在全局作用域,触发一次终止后值一直为true,没有在每次调用函数时重置,导致后续所有调用都会直接进入终止分支,看起来像进程卡住。将标记位移到函数内部作用域,每次调用自动初始化即可彻底解决该问题。
内容的提问来源于stack exchange,提问作者j. cole
相关产品推荐
相关产品推荐

