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

Node.js中如何实现并发安全的目录存在性保障函数?

Node.js 并发安全的目录创建函数实现验证

我需要编写一个并发安全的Node.js函数,确保目标目录不存在时自动创建。以下是我的实现代码:

const creatingDirectories = new Map();

async function ensureDirectoryExists(targetPath) {
  if (!creatingDirectories.has(targetPath)) {
    const mkdirPromise = fs.promises.mkdir(targetPath, { recursive: true });
    creatingDirectories.set(targetPath, mkdirPromise);
  }

  try {
    await creatingDirectories.get(targetPath);
  } catch (err) {
    console.error(`Error creating directory ${targetPath}:`, err);
    throw err;
  }
}

我不确定这个实现是否正确:会不会有多个请求场景下,多个"线程"进入第一个if代码块并重复调用fs.promises.mkdir?补充说明:我知道Node.js是单线程的,这可能不是问题,但还是拿不准。这个函数会用在HTTP请求处理场景,存在并发请求的情况。


你的实现是完全并发安全的,核心原因基于Node.js的单线程事件循环特性:

  • Node.js的同步代码执行是串行的,所有进入ensureDirectoryExists函数的请求,其if判断、Map.set这些同步逻辑会依次执行,不会出现多个请求同时进入if代码块的情况。
  • 第一个请求会创建mkdirPromise并存入Map,后续所有针对同一targetPath的请求,都会直接等待这个已存在的Promise完成,不会重复触发fs.promises.mkdir调用。
  • 即使mkdir因为异步I/O挂起,后续请求的同步判断逻辑依然会先执行,看到Map中已有对应的Promise,就会跳过创建步骤。

额外补充两个优化细节:

  • 虽然fs.promises.mkdir的recursive: true参数本身会保证目录存在时不报错,但你的实现已经从根源避免了重复调用,更高效。
  • 如果mkdir操作失败,Map中会留存失败的Promise,后续请求都会触发相同错误。如果需要支持失败后重试,可以在catch块中移除对应路径的记录:
catch (err) {
  console.error(`Error creating directory ${targetPath}:`, err);
  creatingDirectories.delete(targetPath); // 移除失败的Promise,允许后续重试
  throw err;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 08:17:37