- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我想知道我的小 Node 脚本是否毫无意义或过度使用异步/等待。我的目标是尝试尽可能多地并行查找和解析文件。我的想法是它会更快。
我的 Node 脚本遍历目录和任何子目录并查找 .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);
最佳答案
await
通常在特定代码块需要等待 Promise 然后在完成之前用它做一些事情时很有用(可能涉及等待 另一个 事后 promise )。如果唯一的 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
所做的修复)
关于javascript - 异步/等待矫枉过正?我是否不必要地使用异步和等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57618626/
我有一个对象需要序列化为 EDI 格式。对于这个例子,我们假设它是一辆汽车。汽车可能不是 b/c 选项随时间变化的最佳示例,但对于真实对象,枚举永远不会改变。 我有很多像下面这样的应用了自定义属性的枚
我正在从 Beginning Javascript 学习 Javascript(很有趣!),书中的一个特定示例似乎有点矫枉过正。我知道他们有时会做一些严格来说不是最佳实践的事情 - 例如使用 docu
我应该使用 NSNumber 还是字符串来保存一个简单的“playerID 号码”,现在它是一个整数,因为我想用 Core Data 保存它? 在我的数据模型中,我将 playerID 设置为整数 1
我目前正在做一些网络相关的事情, public void postData() { HttpClient httpclient = new DefaultHttpClient(); HttpPost
我们正在建立一个我们可以使用的 Laravel 4 基础项目。我想创建一个默认路由规则,让开发人员可以轻松地创建新页面,而不必担心向 Controller 添加路由,但可以为任何更复杂的路由/ Con
已在所有 SO 帖子中努力搜索,但仍找不到答案。我的动画很长,很抱歉发了这么长的帖子! 它在 Chrome 上运行良好,但在 Firefox 30.0 上运行不正常,我不明白为什么。 我真的需要这么多
您好,我目前正在为我的项目使用 channel API。我的客户端是一个标牌播放器,它仅在用户更改媒体内容时才从 App Engine 服务器接收数据。 Appengine 每天只向客户端发送一次或两
我开始将 WebApi 和 OData 集成到测试平台应用程序中。让我们保持简单并坚持使用一个域实体 Customer。显然我会有一个 MVC Controller 。搜索得到它自己的 View 模型
两个问题合而为一... 对于实时视频处理应用程序,我有许多函数每帧调用多次。听取有关 const 和按引用传递的建议,这些函数的签名有点像这样 void processSomething(const
我是一名优秀的程序员,十分优秀!