![](/img/trans.png)
[英]Understanding promises async/await using parseCSV, what am I missing?
[英]Async/Await overkill? Am I unnecessarily using async and await?
我想知道我的小节点脚本是无意义还是过度使用async / await。 我的目标是尝试尽可能并行地查找和解析尽可能多的文件。 我的想法是它会更快。
我的节点脚本遍历目录和任何子目录并查找.docx文件。 当它找到它们时,它会通过Mammoth将它们转换为.html文件。 它只是将它们放在类似的目录结构中。
我的代码有效但是我用async / await过度了吗? 有没有我可以消除它们使用的地方,因为没有理由在我所在的地方使用它们?
const createTempDirs = async (catMap) => {
try {
const dirPromises = catMap.map((cat) => fs.mkdir(`issue/${cat.abv}`, {
recursive: true,
}));
await Promise.all(dirPromises);
} catch (error) {
console.log(error);
}
};
const writeToFile = (fileName) => {
return async (result) => {
//return await fs.writeFile(`issue/${fileName.replace('.docx', '.html')}`);
try {
const [
,
category,
...parts
] = fileName.split(' ');
await createTempDirs(catMap),
await fs.writeFile(`issue/${getShortCatName(category)}/${fileName.replace('.docx', '.html')}`, result.value);
} catch (error) {
console.log(error);
}
};
}
const fileToHTML = async (file, dirPath) => {
try {
const fileDetails = await fs.lstat(dirPath + file);
if (fileDetails.isDirectory()) {
walkDir(dirPath + addTrailingSlash(file));
}
if (!fileDetails.isDirectory() && path.extname(file) === '.docx') {
mammoth.convertToHtml({
path: dirPath + file,
}, conversionOptions).then(writeToFile(file));
}
} catch (error) {
console.log(error);
}
};
const processFiles = async (files, dirPath) => {
try {
const filePromises = files.map(file => fileToHTML(file, dirPath));
return await Promise.all(filePromises);
} catch (error) {
console.log(error);
}
};
const walkDir = async (dirPath) => {
try {
const files = await fs.readdir(dirPath);
processFiles(files, dirPath);
} catch (error) {
console.log(error);
}
};
walkDir(dirPath);
当一个特定的代码块需要等待一个Promise 然后在完成之前对它做一些事情 (可能涉及等待另一个 Promise之后)时, await
通常很有用。 如果唯一的await
是在函数的最后一个实线上,那么返回Promise就更有意义了。
至于try
/ catch
,一般的想法是在可以适当处理它们的级别捕获错误。 因此,例如,如果您想在出现问题时完全停止, 只需 catch
最外层的调用,例如:
const createTempDirs = (catMap) => Promise.all(
catMap.map((cat) => fs.mkdir(`issue/${cat.abv}`, {
recursive: true,
}))
);
const writeToFile = (fileName) => {
return async (result) => {
//return await fs.writeFile(`issue/${fileName.replace('.docx', '.html')}`);
const [
,
category,
...parts
] = fileName.split(' ');
await createTempDirs(catMap);
await fs.writeFile(`issue/${getShortCatName(category)}/${fileName.replace('.docx', '.html')}`, result.value);
};
};
const fileToHTML = async (file, dirPath) => {
const fileDetails = await fs.lstat(dirPath + file);
if (fileDetails.isDirectory()) {
// see below line - remember to await or return every Promise created!
await walkDir(dirPath + addTrailingSlash(file));
}
if (!fileDetails.isDirectory() && path.extname(file) === '.docx') {
// see below line - remember to await or return every Promise created!
return mammoth.convertToHtml({
path: dirPath + file,
}, conversionOptions).then(writeToFile(file));
}
};
const processFiles = (files, dirPath) => Promise.all(files.map(file => fileToHTML(file, dirPath)));
const walkDir = async (dirPath) => {
const files = await fs.readdir(dirPath);
processFiles(files, dirPath);
};
然后,只在入口点catch
walkDir
的调用:
walkDir(dirPath)
.catch((err) => {
// There was an error somewhere
});
如果你想在子调用中出现错误时继续处理某个点,那么在那一点捕获错误,例如,如果单个writeFile
可能失败,但你不希望错误渗透到调用链中并停止一切,在writeFile
的调用者中try/catch
:
const writeToFile = (fileName) => {
return async (result) => {
const [
,
category,
...parts
] = fileName.split(' ');
await createTempDirs(catMap);
try {
await fs.writeFile(`issue/${getShortCatName(category)}/${fileName.replace('.docx', '.html')}`, result.value);
} catch(e) {
// writeFile failed, but the rest of the script will continue on as normal
// the error, since it was caught here,
// WILL NOT BE passed up to the caller of writeToFile
}
};
};
确保await
或return
您在入口点之后创建的每个Promise,以便错误将正确地传递给Promise链。 (参见对fileToHTML
的修复)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.