![](/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.