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

如何利用Async/Await与fs.readFile将文件内容存储到变量?

问题描述

以下是我的代码:

const fs = require('fs'); // const util = require('util');
let text = ``;
const files = [`head.txt`,`body.txt`,`leg.txt`,`feet.txt`];
let head,body,leg,feet = ``;
//const readFile = util.promisify(fs.readFile);

function isCompleted(err,data) {
  if (err) {
    throw err;
  }
  text = data.toString();
  proceedData()
}

function proceedData() {
  console.log(text);
  return text;
}

function readFileBody() {
  fs.readFile(files[1], 'utf8', isCompleted);
}

async function printFiles () {
  //head = await fs.readFile(files[0], 'utf8', (err,data) => {if (err) {throw err;}else {head += ` ${data}`}});
  body = await readFileBody();
  //await fs.readFile(files[2], 'utf8', isCompleted);
  //await fs.readFile(files[3], 'utf8', isCompleted);
}

printFiles();

遇到的问题:

  • 在全局作用域中console.log(body)时,返回undefined;
  • 在printFiles函数内部(无return)console.log(body)时,同样返回undefined;
  • 但在isCompleted函数内部console.log(text)能得到文件内容。

请问如何将文件内容存储到变量中?


解决方案

核心问题在于你混用了回调函数和async/await,而readFileBody函数并没有返回一个Promise,所以await readFileBody()根本不会等待文件读取完成就直接执行后续代码,导致body变量还没被赋值就被访问了。

下面给你几个清晰的改造方案:

方案1:使用fs.promises(推荐,现代Node.js原生支持)

Node.js从v10开始就内置了Promise化的fs API,直接用它可以避免回调地狱,完美配合async/await:

const fs = require('fs').promises; // 直接使用promises版本
const files = [`head.txt`,`body.txt`,`leg.txt`,`feet.txt`];
let head, body, leg, feet;

async function printFiles () {
  // 按顺序读取文件并赋值给对应变量
  head = await fs.readFile(files[0], 'utf8');
  body = await fs.readFile(files[1], 'utf8');
  leg = await fs.readFile(files[2], 'utf8');
  feet = await fs.readFile(files[3], 'utf8');

  // 现在可以正常访问这些变量了
  console.log('body内容:', body);
  return { head, body, leg, feet };
}

// 调用async函数需要处理Promise
printFiles()
  .then(result => {
    console.log('所有文件内容:', result);
    // 这里也能访问全局变量或者result里的内容
  })
  .catch(err => console.error('读取文件出错:', err));

方案2:把readFileBody改造成返回Promise的函数

如果你不想用fs.promises,可以手动把回调式的函数包装成Promise:

const fs = require('fs');
const files = [`head.txt`,`body.txt`,`leg.txt`,`feet.txt`];
let body;

// 包装readFile为返回Promise的函数
function readFileBody() {
  return new Promise((resolve, reject) => {
    fs.readFile(files[1], 'utf8', (err, data) => {
      if (err) {
        reject(err); // 出错时reject
      } else {
        resolve(data); // 成功时返回文件内容
      }
    });
  });
}

async function printFiles () {
  body = await readFileBody();
  console.log('body内容:', body); // 现在能正常打印了
}

printFiles().catch(err => console.error(err));

方案3:使用util.promisify(兼容旧版Node.js)

你代码里注释掉了util.promisify,这也是一个把回调函数转成Promise的方法:

const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile); // 把fs.readFile转成Promise版本
const files = [`head.txt`,`body.txt`,`leg.txt`,`feet.txt`];
let body;

async function printFiles () {
  body = await readFile(files[1], 'utf8');
  console.log('body内容:', body);
}

printFiles().catch(err => console.error(err));

额外说明:为什么全局作用域打印body会是undefined?

因为printFiles是异步函数,它的执行不会阻塞主线程。当你在全局作用域打印body时,printFiles里的await readFileBody()还没执行完,文件内容还没赋值给body,所以自然是undefined。

如果要在全局作用域访问异步获取的内容,必须等待printFiles的Promise完成,比如用.then()或者在另一个async函数里等待它。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:08:32