我有这个功能用于从远程服务器删除特定的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被复制到文件夹并立即删除旧的。我的删除功能是否有问题,允许应用程序在完成删除之前继续下一步?
答案 0 :(得分:1)
{
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
这样的库,这些库有办法解决这个问题。
答案 1 :(得分:1)
如果没有看到你的copyJars函数如何解决这个问题,这看起来像是经典的synchronous vs asynchronous issue。
您正在使用带有回调的异步函数fs.readFile 。如果我理解Node.js如何正常工作的基础,它将查找和打开文件并将内容读取到操作系统的操作,当完成后,操作系统返回到节点并说“在这里”是"然后节点用文件数据执行回调。这意味着当操作系统关闭您要删除的文件时,节点将继续执行似乎是您的copyJars函数的代码。根据操作系统使用所需信息返回节点进程的速度,这可能不会按预期顺序发生。
有些解决方案可能是:
您可以使用fs.readFileSync。这将同步执行并在执行此操作时暂停其他代码的执行。 deleteJars听起来不像是一次性的事情,所以这可能不是最有效的解决方案。