函数执行不按顺序发生 - node.js

时间:2018-03-05 15:43:54

标签: node.js function

我有这个功能用于从远程服务器删除特定的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被复制到文件夹并立即删除旧的。我的删除功能是否有问题,允许应用程序在完成删除之前继续下一步?

2 个答案:

答案 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函数的代码。根据操作系统使用所需信息返回节点进程的速度,这可能不会按预期顺序发生。

有些解决方案可能是:

  1. 您可以使用fs.readFileSync。这将同步执行并在执行此操作时暂停其他代码的执行。 deleteJars听起来不像是一次性的事情,所以这可能不是最有效的解决方案。

  2. 您可以实施promises或查看async / await