我正在编写一个电子程序,它将CSV文件作为输入,并根据CSV内容和文件存在进行文件操作(这是为了管理MAME街机)。
为了在UI端有一个进度条,我已经将代码从完全同步(因为它更容易)转换为异步。
当处理CSV文件中的所有行并且复制或删除所有zip文件时,我无法找到如何可靠地向用户显示消息。
这是一个(简化的)示例方法:
fs.readFile(file, { 'encoding': 'utf8' }, (err, fileContents) => {
let fileCsv = csvparse(fileContents);
let lines = fileCsv.length;
fileCsv.forEach((line) => {
lines--;
let zip = line.name + '.zip';
let sourceRom = path.join(romset, zip);
let destRom = path.join(selection, zip);
this.emit('progress.add', fileCsv.length, fileCsv.length - lines, zip);
if (fs.existsSync(sourceRom) && !fs.existsSync(destRom)) {
fs.copy(sourceRom, destRom, (err) => {
let sourceChd = path.join(romset, game);
if (fs.existsSync(sourceChd)) {
fs.copy(sourceChd, path.join(selection, game), (err) => {
if (lines <= 0) { callback(); } // chd is copied
});
} else {
if (lines <= 0) { callback(); } // no chd, rom is copied
}
});
} else {
if (lines <= 0) { callback(); } // no source found or already exists
}
});
});
问题是CSV文件的处理速度非常快,但文件的复制速度并不快。因此它将lines
计数器递减为0,然后在每次文件复制之后,它发现它为零并触发回调。
如何在所有这些嵌套回调和条件结束时可靠地触发回调?
由于
答案 0 :(得分:1)
我试图更改代码而不会大量覆盖您的样式 - 假设有理由避免像async
,async / await&amp;本机Promises和function processLine({
sourceRom, destRom, romset, game, callback
}) {
if (fs.existsSync(sourceRom) && !fs.existsSync(destRom)) {
fs.copy(sourceRom, destRom, (err) => {
// *really* should handle this error
let sourceChd = path.join(romset, game);
if (fs.existsSync(sourceChd)) {
fs.copy(sourceChd, path.join(selection, game), (err) => {
// *really* should handle this error
callback();
});
} else {
callback();
}
});
} else {
callback() // no source found or already exists
}
}
fs.readFile(file, { 'encoding': 'utf8' }, (err, fileContents) => {
let fileCsv = csvparse(fileContents);
let lines = fileCsv.length;
fileCsv.forEach((line) => {
let zip = line.name + '.zip';
let sourceRom = path.join(romset, zip);
let destRom = path.join(selection, zip);
this.emit('progress.add', fileCsv.length, fileCsv.length - lines, zip);
processLine({ sourceRom, destRom, game, romset, callback: () => {
lines--;
if (lines <= 0) {
callback();
}
}})
});
});
lib。
在处理行之后,您需要递减行。我将处理逻辑拉出到一个函数中以使其更清晰:
$(seq)