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

forEach循环多次返回数据:如何获取最终完整数组?

问题:Node.js异步读取文件后仅输出最终完整数组

我编写了一段Node.js代码,逻辑如下:

  • 先读取上级目录的test.json文件,提取其中的token字段存入数组arr;
  • 遍历arr,根据每个token读取对应目录(如../testing/testing_info/123/info.json)下的info.json文件,解析后提取指定数据存入arr2。

目前代码每次读取完一个info.json就打印arr2,导致多次输出数组(3个文件则打印3次),虽然最终能得到目标数组,但我希望仅获取并访问最终的完整arr2。尝试通过判断arr2.length == arr.length来打印,却未生效,请求解决。

当前输出

[ '1', '0' ]
[
  '1',
  '0',
  '2',
  '0'
]
[
  '1',
  '0',
  '2',
  '0',
  '3',
  '-14.05'
]

期望输出

[
  '1',
  '0',
  '2',
  '0',
  '3',
  '-14.05'
]

原代码

fs.readFile('../testing/test.json', 'utf8', function(err, data) {

  let arr = [];
  var json_parse = JSON.parse(data)
  for (var i = 0; i < json_parse.length; i++) {
    arr.push(json_parse[i].token)
  }
  var arr2 = []
  arr.forEach((function(item) {
    var results_max = []

    fs.readFile('../testing/testing_info/' + item + "/info.json", 'utf8', function(err, data) {

      var parse = JSON.parse(data)

      var response_string = JSON.stringify(data)
      var response_clean = response_string.replace(/["\"[\\%"\\\}"""]+/g, '')
      var response_split = response_clean.split(',')

      var contract_address = response_split[1].split(':')[1]
      var percent_change = response_split[6].split(':')[1]

      arr2.push(contract_address, percent_change)
      results_max.push(percent_change)
      var x_max = Math.max(...results_max)

      console.log(arr2)
    });
  }));
});

尝试的修复代码

if (arr2.length == arr.length) {
  console.log(arr2)
}

解决方案

问题根源

  1. 异步操作时序问题:fs.readFile是异步函数,每次读取完成的回调会独立执行,你在回调里直接打印arr2,导致每次添加数据后就输出一次。
  2. 判断条件错误:每个token对应往arr2里存入2个元素,所以最终arr2的长度应该是arr.length * 2,而非相等。
  3. 冗余的JSON处理:原代码中JSON.parse(data)后又执行JSON.stringify(data),完全多余,直接从解析后的对象提取字段更可靠,避免字符串分割因JSON格式变化(如空格、键顺序改变)出错。

修复方案1:基于回调调整判断逻辑

修改判断条件,并将检查逻辑放在每次数据添加后:

fs.readFile('../testing/test.json', 'utf8', function(err, data) {
  if (err) {
    console.error('读取test.json失败:', err);
    return;
  }

  let arr = [];
  const json_parse = JSON.parse(data);
  for (let i = 0; i < json_parse.length; i++) {
    arr.push(json_parse[i].token);
  }
  const arr2 = [];
  const expectedLength = arr.length * 2; // 每个token对应2个元素

  arr.forEach(function(item) {
    fs.readFile(`../testing/testing_info/${item}/info.json`, 'utf8', function(err, data) {
      if (err) {
        console.error(`读取${item}/info.json失败:`, err);
        return;
      }

      // 直接使用解析后的JSON对象提取字段(推荐)
      const parse = JSON.parse(data);
      // 替换为info.json中实际对应的字段名
      const contract_address = parse.contractAddress;
      const percent_change = parse.percentChange;

      // 若必须保留原字符串分割逻辑,可启用以下代码
      /*
      const response_string = JSON.stringify(data);
      const response_clean = response_string.replace(/["\"[\\%"\\\}"""]+/g, '');
      const response_split = response_clean.split(',');
      const contract_address = response_split[1].split(':')[1];
      const percent_change = response_split[6].split(':')[1];
      */

      arr2.push(contract_address, percent_change);

      // 检查是否已收集完所有数据
      if (arr2.length === expectedLength) {
        console.log(arr2);
        // 此处可添加后续处理逻辑
      }
    });
  });
});

修复方案2:使用Promise + async/await(推荐)

这种方式让异步代码更易读,且能确保所有操作完成后再处理最终结果:

const fs = require('fs').promises; // 使用Promise版本的fs模块

async function processData() {
  try {
    // 读取test.json并提取tokens
    const testData = await fs.readFile('../testing/test.json', 'utf8');
    const jsonParse = JSON.parse(testData);
    const arr = jsonParse.map(item => item.token);

    const arr2 = [];
    // 遍历每个token,依次读取对应info.json
    for (const item of arr) {
      const infoData = await fs.readFile(`../testing/testing_info/${item}/info.json`, 'utf8');
      const infoParse = JSON.parse(infoData);
      // 替换为info.json中实际对应的字段名
      const contract_address = infoParse.contractAddress;
      const percent_change = infoParse.percentChange;
      arr2.push(contract_address, percent_change);
    }

    // 所有异步操作完成后打印最终数组
    console.log(arr2);
    // 此处可添加后续处理逻辑
  } catch (err) {
    console.error('处理过程出错:', err);
  }
}

processData();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 03:06:38