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

Node.js中await未等待fs.readdir执行完成导致数组为空问题

问题根因

你的await没生效的核心问题出在这两点:

  • async关键字不会自动等待函数内部的所有异步操作,只有当函数内部返回Promise、或者await了Promise对象时,外部的await才会等对应异步逻辑执行完再往下走。
  • 你用的fs.readdir是回调风格的异步API,调用后会立刻把回调逻辑塞进事件队列,函数本身直接同步执行完,返回一个resolve值为undefined的Promise。等外部await判定执行完成、开始打印数组的时候,读目录的回调还没触发,filesToMove自然是空的。
修复方法

两种常用实现,按需选就行:

方法1:直接用fs的Promise版API

Node.js 10及以上版本自带fs/promises模块,所有API都返回Promise,直接配合await写就不会有等待问题:

// 注意引入promise版本的fs模块
const fs = require('fs/promises');
let filesToMove = [];

async function readFiles() {
  const testFolder = "./files_to_move/";
  const files = await fs.readdir(testFolder);
  files.forEach(file => {
    filesToMove.push(file);
    console.log("done");
  });
}

async function printFiles() {
  await readFiles();
  console.log(filesToMove.length);
  filesToMove.forEach(item => console.log(item));
}

// 不要忘记调用入口函数
printFiles().catch(err => console.error('执行出错:', err));

更推荐的写法是不要用全局数组存文件列表,直接在readFiles里把拿到的files返回,外部用const files = await readFiles()接收就行,能避免全局变量带来的状态混乱。

方法2:手动包装回调为Promise

如果是低版本Node环境用不了fs/promises,可以自己把回调逻辑包成Promise:

const fs = require('fs');
let filesToMove = [];

async function readFiles() {
  const testFolder = "./files_to_move/";
  return new Promise((resolve, reject) => {
    fs.readdir(testFolder, (err, files) => {
      if (err) {
        reject(err);
        return;
      }
      files.forEach(file => {
        filesToMove.push(file);
        console.log("done");
      });
      resolve();
    });
  });
}

async function printFiles() {
  await readFiles();
  console.log(filesToMove.length);
  filesToMove.forEach(item => console.log(item));
}

printFiles().catch(err => console.error('执行出错:', err));

补充:所有异步IO操作都要加错误捕获,不然遇到目录不存在、权限不够的情况,程序会直接抛出未捕获异常崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:27:26