You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ExpressJS与NodeJS页面刷新数组重复:需首次加载并单次输出

问题解决思路

核心问题分析

  • 全局数组污染:logtraceArr定义在路由处理函数外部,属于模块级变量,每次请求都会持续往数组里追加数据,导致后续请求返回重复内容。
  • 异步操作未等待:文件读取、解析都是异步操作,但代码在触发这些操作后立刻调用res.send(),此时异步任务还未完成,数组还没填充数据,所以首次请求返回空数组。

修复后的完整代码

var express = require("express");
var router = express.Router();
const fs = require("fs").promises; // 使用fs promise API简化异步处理
const path = require("path");
const readline = require('readline');

const directoryPath = path.resolve(__dirname,"../logtrace-filestore/edepoze-logs");

router.get("/", async function(req,res,next){
    // 每次请求都创建新数组,避免全局污染
    let logtraceArr = [];

    // 解析单条匹配内容
    const fetchFileContentParsed = (fileContentObj) => {
        const logtraceObj = {
            Direction : '',
            FromServer: '',
            ToServer:''
        };
        const pipearray = fileContentObj.toString().split("|");
        // 原循环无意义,直接取pipearray[5]即可
        if (pipearray[5]) {
            const Direction = pipearray[5].split("::");
            logtraceObj.Direction = Direction.length === 2 ? Direction[1] : "";
        }
        logtraceArr.push(logtraceObj);
    };

    // 读取单个文件并解析
    const processSingleFile = async (file) => {
        const filePath = path.join(directoryPath, file);
        const readStream = fs.createReadStream(filePath);
        const rl = readline.createInterface({
            input: readStream,
            crlfDelay: Infinity
        });

        // 用Promise包裹readline的异步事件,确保文件处理完成后再返回
        return new Promise((resolve) => {
            rl.on('line', (line) => {
                const regExp = /\[Event([^]+\])/g;
                const matchedContent = line.match(regExp);
                if (matchedContent) {
                    fetchFileContentParsed(matchedContent);
                }
            });
            rl.on('close', resolve);
        });
    };

    // 读取目录下所有文件并处理
    const readFiles = async (dirname) => {
        const filenames = await fs.readdir(dirname);
        // 并行处理所有文件
        await Promise.all(filenames.map(processSingleFile));
    };

    try {
        // 等待所有文件读取解析完成
        await readFiles(directoryPath);
        
        res.header("Access-Control-Allow-Origin", "*");
        res.contentType('application/json');
        res.send(logtraceArr);
    } catch (err) {
        // 处理错误,返回500状态码
        next(err);
    }
});

module.exports = router;

关键修改点说明

  • 移除全局数组:将logtraceArr移到路由处理函数内部,每次请求都会创建新数组,避免重复追加数据。
  • 异步操作Promise化:
    • 使用fs.promises替代回调式的fs.readdir,简化异步流程。
    • 用Promise包裹readline的事件监听,确保单个文件的所有行处理完成后再继续执行。
  • 等待异步任务完成:用await等待readFiles完成所有文件的读取和解析,再发送响应,保证首次请求就能返回填充好的数据。
  • 优化冗余代码:移除原代码中无意义的for循环,直接处理pipearray[5]。

内容的提问来源于stack exchange,提问作者SaiPrasad_SP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:50:22