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

Node.js异步爬虫执行完成后如何将结果正确写入本地txt文件

问题解决方案

核心问题说明

  • https.get 为回调风格API,未封装为Promise时,for await 不会等待请求返回结果,只会瞬间完成所有请求的发起,导致后续写文件逻辑提前执行
  • await res.on("end", ...) 属于无效写法:事件监听方法on返回的是事件发射器实例,不是Promise,无法通过await等待回调执行

改造后完整代码

const https = require("https");
const fs = require("fs");
const readline = require("readline");
const path = require("path");

// 封装单个URL爬取逻辑,返回Promise
function fetchUrl(url) {
  return new Promise((resolve) => {
    https
      .get(url, (res) => {
        const { statusCode } = res;
        let error;
        if (statusCode !== 200) {
          error = new Error("Request Failed.\n" + `Status Code: ${statusCode}`);
        }
        if (error) {
          const firstPath = url.split("/")[7];
          const result = `${firstPath} - nothing found`;
          console.error("data : " + result);
          res.resume();
          resolve(result);
          return;
        }
        res.setEncoding("utf8");
        let rawData = "";
        res.on("data", (chunk) => {
          rawData += chunk;
        });
        res.on("end", () => {
          try {
            const parsedData = JSON.parse(rawData);
            const parsedResult = parsedData["data"]["id"] + " - " + parsedData["data"]["price"];
            console.log("data : " + parsedResult);
            resolve(parsedResult);
          } catch (e) {
            console.error(e.message);
            resolve(`${url} - parse JSON failed: ${e.message}`);
          }
        });
      })
      .on("error", (e) => {
        const errorResult = `${url} - request error: ${e.message}`;
        console.error(errorResult);
        resolve(errorResult);
      });
  })
}

(async function main() {
  // 1. 读取所有URL
  const urls = [];
  const fileStream = fs.createReadStream("urls.txt");
  const rl = readline.createInterface({
    input: fileStream,
    crlfDelay: Infinity,
  });
  for await (let line of rl) {
    urls.push(line);
  }
  rl.close();

  // 2. 并发执行所有爬取任务,等待全部完成
  const results = await Promise.all(urls.map(url => fetchUrl(url)));

  // 3. 所有任务完成后写入文件
  await fs.promises.writeFile('result.txt', results.join('\n'));
  console.log("File write successfull");
})();

改动说明

  • 将单个URL的爬取逻辑封装为返回Promise的fetchUrl函数,所有成功/错误结果都通过resolve返回,统一收集
  • 使用Promise.all等待所有爬取任务全部执行完成后,再调用写文件逻辑,保证不会提前执行
  • 写文件时将数组转为换行分隔的字符串,避免默认的逗号分隔格式不符合预期
  • 移除了全局变量存储结果的逻辑,改为通过Promise返回值收集,避免全局变量污染和异步时序导致的数据丢失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 03:54:03