我有这个功能从远程服务器删除特定的jar:
deleteJars: function(appDir, version, callback) {
fs.readFile('/file/location', function(err, data) {
if(err) throw err;
var array = data.toString().split("\n");
for(i in array) {
if (array[i].indexOf('worker') > -1){
var ip = array[i].split(" ");
var ssh = new SSH2Utils();
var server = {
host: ip[0],
username: username,
password: password
};
var myfiles = ssh.exec(server, 'rm ' + appDir + '/' + version + '/jars/myjar*.jar', function(err,stdout,stderr, server, conn, response){
if(err) console.log('No jars to delete');
conn.end();
callback(response);
});
}
}
});
}
它在我的应用程序中被调用:
runningService.deleteJars(appDir, version, function() {
});
在此之后,我立即呼吁copyJars finction将新的jar文件复制到同一位置,然后运行一个使用trhe jar的作业。我的问题是有时复制是在删除之前完成的,所以新的jar被复制到文件夹并立即删除旧的。我的删除功能是否有问题,允许应用程序在完成删除之前继续执行下一步?
{
deleteJars: function(appDir, version, callback) {
fs.readFile('/file/location', function (err, data) {
if (err) throw err;
var array = data.toString().split("\n");
const promises = [];
for (i in array) {
if (array[i].indexOf('worker') > -1) {
var ip = array[i].split(" ");
var ssh = new SSH2Utils();
var server = {
host: ip[0],
username: username,
password: password
};
promises.push(
new Promise((resolve, reject) => {
ssh.exec(server, 'rm ' + appDir + '/' + version + '/jars/myjar*.jar', function (err, stdout, stderr, server, conn, response) {
if (err) reject('No jars to delete');
conn.end();
resolve(response);
})
})
)
}
}
Promise.all(promises).then((results) => { // results will be in order
// use the results array
callback(null, results);
}).catch(err => {
console.log(err);
})
});
}
}
使用回调,维护顺序可能有点困难 - 但使用Promises - 我们有一个名为Promise.all
的简单API,您可以像上面一样使用它。要继续使用回调,您可以查看像async
这样的库,这些库有办法解决这个问题。
如果没有看到你如何使用copyJars函数,这看起来像一个经典的synchronous vs asynchronous issue。
您正在使用带有回调的异步函数fs.readFile。如果我理解了Node.js如何正常工作的基础,它将查找和打开文件并将内容读取到操作系统的操作,当完成后,操作系统返回到节点并说“这里是”并且然后节点用文件数据执行回调。这意味着当操作系统关闭您要删除的文件时,节点将继续执行似乎是您的copyJars函数的代码。根据操作系统使用所需信息返回节点进程的速度,这可能不会按预期顺序发生。
一些解决方案可能是: