我构建了一个Angular / Node应用程序,用于重命名网络文件夹中的文件。它重命名的文件数量在300到500之间。我使用await,以便在重命名完成时得到通知。每次运行需要8到10分钟,并且由于我正在使用await而无法同时重命名。
我需要传递重命名文件的数量,并且需要向用户显示重命名已经完成。如果我不使用async / await,我的前端角度如何知道重命名已完成?
我的完整代码在这里:https://github.com/ericute/renamer
我在这里遇到麻烦:
await walk(folderPath, function(err, results) {
if (err) throw err;
results.forEach(file => {
if (fs.lstatSync(file).isFile) {
fileCounter++;
}
let fileBasename = path.basename(file);
let filePath = path.dirname(file);
if (!filesForRenaming[path.basename(file)]) {
//In a javascript forEach loop,
//return is the equivalent of continue
//https://stackoverflow.com/questions/31399411/go-to-next-iteration-in-javascript-foreach-loop
return;
}
let description = filesForRenaming[path.basename(file)].description;
// Process instances where the absolute file name exceeds 255 characters.
let tempNewName = path.resolve(filePath, description + "_" + fileBasename);
let tempNewNameLength = tempNewName.length;
let newName = '';
if (tempNewNameLength > 255) {
let excess = 254 - tempNewNameLength;
if (description.length > Math.abs(excess)) {
description = description.substring(0, (description.length - Math.abs(excess)));
}
newName = path.resolve(filePath, description + "_" + fileBasename);
} else {
newName = tempNewName;
}
renamedFiles++;
// Actual File Renaming
fs.renameSync(file, newName, (err) => {
if (err) {
errList.push(err);
}
renamedFiles++;
});
});
if (Object.keys(errList).length > 0) {
res.send({"status":"error", "errors": errList});
} else {
res.send({
"status":"success",
"filesFoundInDocData": Object.keys(filesForRenaming).length,
"filesFound": fileCounter,
"renamedFiles": renamedFiles,
"startDate": startDate
});
}
});
答案 0 :(得分:0)
如果您使用任何同步方法,则基本上是在阻塞事件循环。您必须更改代码的整体结构,并开始在各处使用promise。您应该能够以角度创建另一个服务,该服务使用timeInterval和GET请求(最简单的方法)检查重命名过程是否完成。例如,您可以设置angular以从“ / isRenameCompleted”中获取数据,并在结果为true或其他情况时警告用户。要获得实时结果,您必须切换到socket-io。一个针对1个客户端的快速解决方案(因为您需要为每个请求存储唯一的ID,并相应地获取promise)可能是这样的:
1:在代码顶部创建两个全局变量
var filesStatus="waiting"
var pendingFiles=[]
2:在您的重命名逻辑路由内,使用for循环将每个文件推送到promise数组,并开始异步等待重命名过程完成
pendingFiles.push(fsPromises.rename(oldName,newName))
Promise.all(pendingFiles)
.then(values => {
filesStatus = "done"
})
.catch(error => {
filesStatus = "error"
});
filesStatus="pending"
3:现在添加一条新的路由/isRenameCompleted
,它将具有如下所示的报告逻辑
router.get('/isRenameCompleted', (req, res, next) => {
if (filesStatus==="pending"){
res.end("please wait")
} else if (filesStatus==="done"){
res.end("done! your files renamed")
}
}