У меня есть следующий код javascript, написанный для запуска в node.js:
const fs = require("fs");
const path = require("path");
var copy = function(paramSource, paramDestination, paramCallback) {
if (fs.existsSync(paramDestination)) {
return paramCallback("Destination Exists"); //TODO make formal error code
} else {
fs.lstat(paramSource, function(error, sourceStats) {
if (error) {
return paramCallback(error);
} else {
if (sourceStats.isDirectory()) {
fs.readdir(paramSource, function(error, sourceContents) {
if (error) {
return paramCallback(error);
} else {
fs.mkdir(paramDestination, sourceStats.mode, function(error) {
if (error) {
paramCallback(error);
} else {
if (sourceContents.length > 0) {
sourceContents.forEach(function(sourceChild) {
copy(path.join(paramSource, sourceChild), path.join(paramDestination, sourceChild), paramCallback);
});
}
return paramCallback(null, paramDestination);
}
});
}
});
} else {
var sourceFile = fs.createReadStream(paramSource);
var destinationFile = fs.createWriteStream(paramDestination); //TODO permissions
sourceFile.on("error", function(error) {
return paramCallback(error);
});
destinationFile.on("error", function(error) {
return paramCallback(error);
});
sourceFile.on("close", function() {
//return paramCallback(null, paramSource);
});
destinationFile.on("close", function() {
return paramCallback(null, paramDestination);
});
sourceFile.pipe(destinationFile);
}
}
});
}
};
var entities = 0;
copy("/home/fatalkeystroke/testing/directory_01", "/home/fatalkeystroke/testing/directory_01_copy", function(error, name) {
if (error) {
console.log(error);
} else {
console.log(name);
entities++;
}
});
console.log("Copied " + entities + " entities.");
console.log("Program Done.");
Это тестовая версия из приложения, над которым я работаю. Я хотел бы сохранить асинхронный характер функции copy(), однако я также хочу узнать, когда полная копия завершена (как подразумевает код, связанный с entities
). Причина состоит в том, что я хочу сказать, когда это будет сделано, но также реализовать возможности отслеживания прогресса.
Есть ли способ синхронно ждать завершения рекурсивной асинхронной функции в Javascript?
Это можно сделать с последовательным исполнителем nsynjs. Ваш код преобразуется следующим образом:
var copy = function (src,dst) {
if(nsynFs.lstat(nsynjsCtx, src).data.isDirectory()) {
var files = nsynFs.readdir(nsynjsCtx, src).data;
nsynFs.mkdir(nsynjsCtx,dst);
for(var i=0; i<files.length; i++) {
var f=files[i];
console.log(f);
copy(src+"/"+f, dst+"/"+f);
}
}
else { // is File
var input = nsynFs.open(nsynjsCtx,src,'r').data;
var output = nsynFs.open(nsynjsCtx,dst,'w').data;
var buf = Buffer.alloc(4096);
while(true) {
var readCnt = nsynFs.read(nsynjsCtx,input,buf,0,4096,null).data;
if(!readCnt)
break;
nsynFs.write(nsynjsCtx,output,buf,0,readCnt,null);
}
nsynFs.close(nsynjsCtx,input);
nsynFs.close(nsynjsCtx,output);
}
};
copy("test1","test2");
См. Полный рабочий пример здесь: /index.js