我正在编写一个函数 createFile
来在目录中创建一个文件,除非它已经存在。我正在使用 Node.js native fs
包来执行所有文件操作。我想让我的函数异步,所以我将所有 fs
函数包装在 promises 中:
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
才能始终。
这是功能代码:
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);
}
}());
}
}));
}
我缺少什么以及如何将我的函数变成真正的异步函数?
最佳答案
occasional incorrect behavior, namely, if a directory for the file didn't exist and I wanted to create one the directory would be created empty without the file
这可能是由 writeFilePromise
尤其是 mkDirPromise
的不正确实现引起的。 fs.writeFile
和 fs.mkdir
是异步的,但 promise 是同步解决的。应该是:
function writeFilePromise(writePath, textContent) {
return new Promise((resolve, reject) => {
fs.writeFile(writePath, textContent, (err) => {
if (err)
reject(err);
else
resolve();
});
});
}
function mkDirPromise(dir) {
return new Promise(((resolve, reject) => {
fs.mkdir(path.join(constants.FILES_STORAGE_DIR, dir), (err) => {
if (err)
reject(err);
else
resolve();
});
}));
}
这就是 util.promisify
的用途:
const writeFilePromise = util.promisify(fs.writeFile);
即便如此,这也是一个轮子的重新发明,因为已经有第三方包可以做到这一点甚至更多,即 fs-extra
。
createFile
的控制流很差,并且使用了 promise 构造反模式。因为它使用了async..await
,所以它应该是:
async function createFile(dir, fileName, httpMethod, textContent) {
const searchPath = path.join(ROOT_DIR, dir, fileName);
if (httpMethod === POST && fs.existsSync(searchPath)) {
throw new Error();
} else {
const fileExistsStatus = fs.existsSync(path.join(ROOT_DIR, dir));
if (!fileExistsStatus) {
await mkDirPromise(dir);
}
await writeFilePromise(searchPath, textContent);
}
}
值得一提的是,existsSync
是稳定的 API 方法,可以用它来检查文件是否存在。作为the documentation州,
Note that fs.exists() is deprecated, but fs.existsSync() is not. (The callback parameter to fs.exists() accepts parameters that are inconsistent with other Node.js callbacks. fs.existsSync() does not use a callback.)
关于javascript - 为什么 node.js `fs.existsSync` 在用 promise 包装时不能正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50767829/