Yos*_*Yos 2 javascript asynchronous fs node.js
我正在编写一个函数createFile来在目录中创建一个文件,除非它已经存在。我正在使用 Node.js 本机fs包来执行所有文件操作。我想让我的函数异步,所以我将所有fs函数都封装在 promise 中:
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();
}));
}
Run Code Online (Sandbox Code Playgroud)
然后我还想包装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);
}
}());
}
}));
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么以及如何将我的功能变成真正的异步?
偶尔的不正确行为,即,如果文件目录不存在而我想创建一个目录,则该目录将在没有文件的情况下创建为空
这可能是由 和 的不正确实现引起的writeFilePromise,尤其是mkDirPromise. fs.writeFile并且fs.mkdir是异步的,但承诺是同步解决的。它应该是:
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();
});
}));
}
Run Code Online (Sandbox Code Playgroud)
这util.promisify是为了:
const writeFilePromise = util.promisify(fs.writeFile);
Run Code Online (Sandbox Code Playgroud)
即便如此,这也是一次轮子改造,因为已经有第三方软件包可以做到这一点,甚至更多,即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);
}
}
Run Code Online (Sandbox Code Playgroud)
需要说明的existsSync是,这是一个稳定的API方法,可以用它来检查文件是否存在。正如文档所述,
请注意,不推荐使用 fs.exists(),但不推荐使用 fs.existsSync()。( fs.exists() 的回调参数接受与其他 Node.js 回调不一致的参数。fs.existsSync() 不使用回调。)