我需要以同步方式执行多项任务。 从文件夹及其子文件夹中提取一些文件到一组项目中,然后对其进行临时复制。 这两个任务我设法同步完成。
然后,我需要在数组的每个项目上执行7个任务,并且我需要等待7个任务完成一项,然后再传递到下一个任务。
但是我所做的每一次尝试都以以下顺序结束任务: 例如要处理3个文件:
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 6 7 6 7 6 7.我希望是: 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4 5 6 7 最后两个任务堆叠在一起,并且仅在为每个文件都执行5个“第一”任务时才触发。
在这里,我如何启动脚本:
start();
async function start() {
await listDirToProcess(); // This works
await makeSafeCopy(); // This works as well
for (var currentDCF of dirToProcess) {
Perform the 7 tasks...
}
}
我尝试了一个回调地狱(上一个任务的回调中的所有事情) 我尝试了没有start()函数 我尝试了或多或少的异步/等待关键字 我还尝试了在SO中找到的asyncForEach函数,而不是当前的for-of循环:
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
但是他们都没有成功。
我目前正在使用for(yy的xx)循环遍历数组。
以下是这些任务的摘要:
步骤1 :
将文件复制到另一个文件夹,我就是这样:
// Usage of the function
await copyToSomeDir(stuff, (err) => {
err == 0 ?
log.info('\t\tCopy to xxx went well') :
log.info('\t\tCopy to xxx ended with ' + err + " error ");
});
// Definition of the function
function copyToSomeDir(item, cb) { // Notice i didn't put the async key word
...
cb(i);
}
第2步: 等待外部应用在Step 1输出文件夹上完成工作
// Usage of the function
await execExternJob();
// Definition of the function
function execExternJob() {
log.info("Executing Talend job")
child_process.execSync(cmd_to_exe, (error, stdout, stderr) => {
log.info("job completed for the " + item.entity);
})
}
第3步: 检查上一个外部作业的结果:
// Usage of the function
await checkSuccessfulJob(xxx, (list) => {
...
});
// Definition of the function
function checkSuccessfulJob(xxx, cb) {
...
cb(list);
}
第4步: 用其他文件替换一些文件
// Usage of the function
await OverwriteSucessFile(currentDCF.talendResult.success);
// Definition of the function
function OverwriteSucessFile(list) {
...
};
!!! 这是打破一切的步骤。 !!! 步骤5-6-7: 如果在外部工作期间一切都不顺利,那就做些事情 其他压缩文件夹并将其上传到Web服务(实际上是CMS)。
if (fault) {
fault.forEach((faultyFile) => {
... // Not important
})
} else {
//Usage of the function
await prepareZipFolder(xxx, yyy, (path) => { // Step 5
getUrlFromFile(AlfrescoUrl, (url) => { // Step 6
uploadToCMS(url, path (ok) => { // Step 7
log...
})
});
});
}
这是我认为是有问题的功能的定义:
async function prepareZipFolder(zipFileName, rootZipFolder, callback) {
var zipFile = fs.createWriteStream(path.join(rootZipFolder, zipFileName) + ".zip");
// >>>>>>>>>>> Here is where it pass to the next itteration instead of waiting the end of the archiving. I think ! <<<<<<<<<<<
var archive = archiver('zip', {
zlib: { level: 9 } // Sets the compression level.
});
zipFile.on('close', () => {
callback(path.join(rootZipFolder, zipFileName) + ".zip")
})
zipFile.on('open', (fd) => {
archive.on('error', function (err) { log.info(err) });
archive.pipe(zipFile);
archive.glob("**", { cwd: path.join(rootZipFolder, zipFileName) }, { prefix: zipFileName });
archive.finalize();
})
}
问题在于,当创建.zip fil时,循环传递到下一个项目,而不是等待归档结束。
很长的问题很抱歉,有人可以帮忙吗?
答案 0 :(得分:0)
如果我正确理解,您会不断地将promisized函数与回调函数混合使用(还会发生一些奇怪的事情,例如child_process.execSync(cmd_to_exe, (error, stdout, stderr) => {...
— Sync
函数不使用回调函数,但这可能是一个错字)。
您需要坚持一种方法。如果某些API不提供返回Promise的功能,则仅在它们之前添加await
便不会与Promise兼容。您需要自己寻找另一个API或实现包装函数的功能。
例如,您的第2步:
await execExternJob();
function execExternJob() {
log.info("Executing Talend job")
child_process.execSync(cmd_to_exe, (error, stdout, stderr) => {
log.info("job completed for the " + item.entity);
})
}
可以改写为:
await execExternJob();
function execExternJob() {
log.info("Executing Talend job");
return new Promise((resolve, reject) => {
child_process.exec(cmd_to_exe, (error, stdout, stderr) => {
if (error) {
reject(error);
} else {
log.info("job completed for the " + item.entity);
resolve();
}
});
});
}
以此类推。