首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么node.js `fs.existsSync`在promise中不能很好地工作?

为什么node.js `fs.existsSync`在promise中不能很好地工作?
EN

Stack Overflow用户
提问于 2018-06-09 04:14:12
回答 2查看 3.3K关注 0票数 2

我正在编写一个函数createFile,用于在一个目录中创建一个文件,除非该文件已经存在。我使用Node.js原生fs包来执行所有文件操作。我想让我的函数异步,所以我把所有的fs函数都包装在promises中:

代码语言:javascript
复制
function writeFilePromise(writePath, textContent) {
    return new Promise((resolve, reject) => {
      fs.writeFile(writePath, textContent, (err) => {
        reject();
      });
      resolve();
    });
  }

  function mkDirPromise(dir) {
    return new Promise(((resolve, reject) => {
      fs.mkdir(path.join(constants.FILES_STORAGE_DIR, dir), (err) => {
        reject(err);
      });
      resolve();
    }));
  }

然后我还想在promise中包装fs.existsSync,以完成我的功能,但包装它偶尔会导致不正确的行为,也就是说,如果文件的目录不存在,而我想创建一个目录,则创建的目录将是空的,而不会创建文件。通过调试,我发现只有同步fs.existsSync才能工作,并且始终是。这是函数代码:

代码语言:javascript
复制
function createFile(dir, fileName, httpMethod, textContent) {
    return new Promise(((resolve, reject) => {
      const searchPath = path.join(ROOT_DIR, dir, fileName);
      if (httpMethod === POST && fs.existsSync(searchPath)) {
        reject();
      } else {
        const fileExistsStatus = fs.existsSync(path.join(ROOT_DIR, dir));
        (async function fsOperations() {
          try {
            if (!fileExistsStatus) {
              await mkDirPromise(dir);
            }
            await writeFilePromise(searchPath, textContent);
            resolve();
          } catch (err) {
            reject(err);
          }
        }());
      }
    }));
  }

我遗漏了什么?我怎样才能把我的函数变成真正的异步函数?

EN

回答 2

Stack Overflow用户

发布于 2018-06-09 04:53:37

首先,您构造了writeFilePromisemkDirPromise,以便它们始终是resolve,而不是reject。因为fs.writeFilefs.mkdir是异步的,所以一旦它们启动,线程就会立即转移到resolve()。我想你的意思是..。

代码语言:javascript
复制
function writeFilePromise(writePath, textContent) {
    return new Promise((resolve, reject) => {
        fs.writeFile(writePath, textContent, (err) => {
            if (err) reject();
            else resolve();
        });
    });
}

function mkDirPromise(dir) {
    return new Promise((resolve, reject) => {
        fs.mkdir(path.join(constants.FILES_STORAGE_DIR, dir), (err) => {
            if (err) reject();
            else resolve();
        });
    });
}

fs.exists而言,它已经过时了,所以我不推荐使用它。相反,可以尝试使用fs.access

代码语言:javascript
复制
function accessPromise(dir) {
    return new Promise((resolve, reject) => {
        fs.access(dir, (err) => {
            if (err) reject();
            else resolve();
        });
    });
}

最后,尝试调整使用async函数声明的位置,以确保正确地同步代码:

代码语言:javascript
复制
async function createFile(dir, fileName, httpMethod, textContent) {
    const searchPath = path.join(ROOT_DIR, dir, fileName);
    if (httpMethod === POST && await accessPromise(searchPath)) {
        return false;
    } else {
        const fileExistsStatus = await accessPromise(path.join(ROOT_DIR, dir));
        try {
            if (!fileExistsStatus) {
                await mkDirPromise(dir);
            }
            await writeFilePromise(searchPath, textContent);
            return true;
        } catch (err) {
            return false;
        }
    }
}

记得在调用该函数时使用await createFile(dir, fileName, httpMethod, textContent)

票数 2
EN

Stack Overflow用户

发布于 2018-06-09 04:56:18

首先,考虑用有意义的东西来拒绝,而不仅仅是reject()

由于您考虑的是async和promise,我不推荐使用fs.xxxSync()函数。另外,fs.exists已被弃用,请尝试使用fs.stat()

我猜只有在HTTP方法是POST的情况下才会创建文件,但是在当前的if-else逻辑中,当HTTP方法不是POST时,总是会创建文件。

不需要创建立即调用的异步函数。

试试这个:

代码语言:javascript
复制
function createFile(dir, fileName, httpMethod, textContent) {
    return new Promise((resolve, reject) => {
        const searchPath = path.join(ROOT_DIR, dir, fileName);
        if (httpMethod !== POST) {
            return reject(new Error('Invalid HTTP method'));
        }
        fs.exists(searchPath, (exists) => {
            if (exists) {
                return reject(new Error('Already exists'));
            }
            fs.exists(path.join(ROOT_DIR, dir), async (exists) => {
                try {
                    if (!exists) {
                        await mkDirPromise(dir);
                    }
                    await writeFilePromise(searchPath, textContent);
                    resolve();
                } catch (err) {
                    reject(err);
                }
            });
        });
    });
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50767829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档