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

Node.js中GET请求JSON数据无法存入全局变量及写入文件问题

解决异步GET请求数据无法存入全局变量并写入文件的问题

你碰到的核心问题是JavaScript的异步执行机制——http.get是异步操作,它不会阻塞后续代码运行。你写在两个请求之后的console.log(g_last)和fs.writeFile会在两个请求的end回调触发前就执行,这时候tmp_json还没被赋值,g_last还是初始的0,自然写入的文件是空的。

解决方案:用Promise + async/await管控异步流程

我们可以把每个异步GET请求包装成Promise,再用Promise.all等待所有请求完成后,统一处理数据并写入文件,这样就能保证数据都准备好后再执行写入操作。

步骤1:封装异步GET请求为Promise

先写一个复用的函数,把http.get转换成返回Promise的形式,方便后续用async/await处理:

const fs = require("fs");
const http = require("http");

// 封装异步GET请求为Promise
function httpGet(url) {
  return new Promise((resolve, reject) => {
    http.get(url, (resp) => {
      let data = '';
      resp.on('data', (chunk) => {
        data += chunk;
      });
      resp.on('end', () => {
        try {
          // 解析JSON数据并返回
          const parsedData = JSON.parse(data);
          resolve(parsedData);
        } catch (parseErr) {
          reject(new Error(`解析JSON失败: ${parseErr.message}`));
        }
      });
    }).on("error", (reqErr) => {
      reject(new Error(`请求失败: ${reqErr.message}`));
    });
  });
}

步骤2:用async/await并行处理请求并写入文件

通过async/await和Promise.all,我们可以并行发起两个请求,等待所有请求完成后再处理数据和写入文件:

// 主逻辑函数
async function fetchAndSaveData() {
  const tmp_json = {};
  let g_last = 0;

  try {
    // 并行发起两个请求,等待所有请求完成
    const [server1Data, server2Data] = await Promise.all([
      httpGet('server:api'),
      httpGet('server2:api')
    ]);

    // 将请求结果存入tmp_json
    tmp_json.server1 = server1Data;
    tmp_json.server2 = server2Data;

    // 更新变量g_last(这里取第二个请求的height为例)
    g_last = server2Data.height;
    console.log(g_last); // 输出256

    // 将数据写入文件
    const jsonStr = JSON.stringify(tmp_json);
    fs.writeFile('data.json', jsonStr, 'utf8', (writeErr) => {
      if (writeErr) {
        console.log(`写入文件失败: ${writeErr.message}`);
      } else {
        console.log("数据已成功写入data.json");
      }
    });
  } catch (err) {
    // 捕获请求或解析过程中的错误
    console.log(err.message);
  }
}

// 执行主函数
fetchAndSaveData();

如果你想用fs.createWriteStream写入

如果偏好使用流的方式写入,只需要把上面的fs.writeFile部分替换成以下代码即可,同样要确保在所有请求完成后再写入:

const writeStream = fs.createWriteStream('data.json', 'utf8');
writeStream.write(JSON.stringify(tmp_json));
writeStream.end();

writeStream.on('finish', () => {
  console.log("数据已通过流成功写入文件");
});

writeStream.on('error', (streamErr) => {
  console.log(`写入流出错: ${streamErr.message}`);
});

关键注意点

  • 错误处理:一定要捕获请求、JSON解析和文件写入过程中的错误,避免某个环节出错导致整个流程无响应
  • 请求顺序:如果两个请求有依赖关系(比如需要先获取server1的数据再请求server2),把Promise.all改成顺序执行的await即可,比如先const server1Data = await httpGet('server:api'),再const server2Data = await httpGet('server2:api')
  • 避免全局变量滥用:尽量把数据放在函数内部(比如示例中的tmp_json),减少全局变量的使用,避免异步操作导致的变量污染问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:46:01