Javascript 异步函数中如何停止回调引起的无限循环

Javascript 异步函数中如何停止回调引起的无限循环,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,我的程序中定义了两个异步函数;其中一个ping给定的IP地址(使用模块)并“返回”(通过回调)ping是否成功,另一个创建到给定IP地址的SSH连接(使用模块)并“返回”连接是否成功 当我试图使用readline功能从data.txt文件中读取IP数据时,出现了问题。我使用readline模块读入文件中的每一行,使用回调以阻塞方式调用ping和ssh,然后将这些返回值放入一个数组中供以后使用。我已经能够验证函数是否按照我期望的顺序执行,以及返回值是否真正返回。。但是,当程序到达文件末尾时,它不是

我的程序中定义了两个异步函数;其中一个ping给定的IP地址(使用模块)并“返回”(通过回调)ping是否成功,另一个创建到给定IP地址的SSH连接(使用模块)并“返回”连接是否成功

当我试图使用
readline
功能从
data.txt
文件中读取IP数据时,出现了问题。我使用
readline
模块读入文件中的每一行,使用回调以阻塞方式调用ping和ssh,然后将这些返回值放入一个数组中供以后使用。我已经能够验证函数是否按照我期望的顺序执行,以及返回值是否真正返回。。但是,当程序到达文件末尾时,它不是终止,而是一次又一次地读取文件

SSH函数定义为:

function SSH(ipAdress, callback) {

  connection.on('ready', function(err) {

    if(err) {
      throw err;
      returnValue = "ErrorWithReadyConnection";
      callback(null, returnValue);
    }

    //runs the uptime command once we have SSH'd into the machine
    connection.exec('uptime', function(err, stream) { 

      if(err) {
        throw err;
        returnValue = "ErrorRunningCommandFromSSH";
        callback(null, returnValue);

      }
      else {

        stream.on('close', function(code, signal) {

          //code holds the response from running 'uptime'
          console.log("Stream on close. Code : " + code +
                      ". Signal: " + signal);

          connection.end();
          returnValue = "success";
          callback(null, returnValue);

      }).on('data', function(data) {

       console.log("STDOUT: " + data);
      }).stderr.on('data', function(data) {

          console.log("STDERR: " + data);
        });
      }
    }); 

  //Parameters for the SSH connection
  }).connect({
    host: ip,
    port: 22,
    username: userName,
    privateKey: privateKey,
    passphrase: passPhrase
  }); //connect


  //handle any connection errors done whilst creating a connection
  connection.on('error', function(err) {

    if(err) {
      returnString = "ErrorWaitingForHandshake";
      callback(null, returnString);
    }
  }); //end connect
}
function pingFunc(ip, callback) {

  var returnString;

  //Create a ping session, passing the IP of the machine to ping
  sessions.pingHost(ip, function(error, target) {

    //if error, then examine what type of error has occured
    if(error) {

      if(error instanceof ping.RequestTimedOutError) {
         returnString = "RequestTimedOut";
      }


      //else, different error - output the error string.
      else {
        returnString = "Error";
      }

    } //End error handling

    //else, ping was successful
    else {
      returnString = "Alive";
    }

    callback(null, returnString);
  });

  //return returnString;
}
ping功能定义为:

function SSH(ipAdress, callback) {

  connection.on('ready', function(err) {

    if(err) {
      throw err;
      returnValue = "ErrorWithReadyConnection";
      callback(null, returnValue);
    }

    //runs the uptime command once we have SSH'd into the machine
    connection.exec('uptime', function(err, stream) { 

      if(err) {
        throw err;
        returnValue = "ErrorRunningCommandFromSSH";
        callback(null, returnValue);

      }
      else {

        stream.on('close', function(code, signal) {

          //code holds the response from running 'uptime'
          console.log("Stream on close. Code : " + code +
                      ". Signal: " + signal);

          connection.end();
          returnValue = "success";
          callback(null, returnValue);

      }).on('data', function(data) {

       console.log("STDOUT: " + data);
      }).stderr.on('data', function(data) {

          console.log("STDERR: " + data);
        });
      }
    }); 

  //Parameters for the SSH connection
  }).connect({
    host: ip,
    port: 22,
    username: userName,
    privateKey: privateKey,
    passphrase: passPhrase
  }); //connect


  //handle any connection errors done whilst creating a connection
  connection.on('error', function(err) {

    if(err) {
      returnString = "ErrorWaitingForHandshake";
      callback(null, returnString);
    }
  }); //end connect
}
function pingFunc(ip, callback) {

  var returnString;

  //Create a ping session, passing the IP of the machine to ping
  sessions.pingHost(ip, function(error, target) {

    //if error, then examine what type of error has occured
    if(error) {

      if(error instanceof ping.RequestTimedOutError) {
         returnString = "RequestTimedOut";
      }


      //else, different error - output the error string.
      else {
        returnString = "Error";
      }

    } //End error handling

    //else, ping was successful
    else {
      returnString = "Alive";
    }

    callback(null, returnString);
  });

  //return returnString;
}
我调用函数的代码是:

var allMachines = new Array();

var lineReader = require('readline').createInterface({
  input: require('fs').createReadStream('data.txt');
});

lineReader.on('line', function(line) {

  pingFunc(line, function(err, pingResult) {
    SSH(line, function(err, sshResult) {

       var machineTemp = [{'ping': pingResult, 'ssh': sshResult }];
       allMachines = allMachines.concat(machineTemp);
    })
  })
}
我计划稍后使用
allMachines
数组创建一个JSON文件,但是这个无限循环正在阻止所有潜在的进程。我试图在SSH函数中移动
连接。on('error',…)
,我认为这是导致无限循环的原因,但事实证明这是徒劳的

任何帮助都将不胜感激-谢谢


p.S如果有人知道当
readlines
完成,并且
allMachines
数组已经填充了必要的数据时,我将非常感激!我曾经尝试使用
readline.on('close',…)
,但是在SSH和ping完成执行之前调用它,所以对我来说没有用!再次感谢

您遇到这么多麻烦的原因是您没有在回调中使用error参数。第一个
err
参数的要点是将错误传递回并在继续之前检查它。如果将
null
作为第一个参数传递,即使出现错误,也会自找麻烦。我会从那里开始,然后“扔错球”在异步回调中是完全无用的。它只不过是一个简单的返回,因为它进入了一些异步事件回调基础设施的内部,而这些基础设施什么也做不了。不能对标准异步回调使用异常。正如上面tommy所说,使用回调的error参数将错误传递回来。很好的建议,我修改了代码以反映这一点,但是我仍然得到相同的错误。只是似乎无法找出是什么导致了我的一生“我使用回调以阻塞的方式调用ping和ssh”-等等什么?你遇到这么多麻烦的原因是因为你没有在回调中使用error参数。第一个
err
参数的要点是将错误传递回并在继续之前检查它。如果将
null
作为第一个参数传递,即使出现错误,也会自找麻烦。我会从那里开始,然后“扔错球”在异步回调中是完全无用的。它只不过是一个简单的返回,因为它进入了一些异步事件回调基础设施的内部,而这些基础设施什么也做不了。不能对标准异步回调使用异常。正如上面tommy所说,使用回调的error参数将错误传递回来。很好的建议,我修改了代码以反映这一点,但是我仍然得到相同的错误。只是似乎无法找出是什么导致了我的一生“我使用回调以阻塞方式调用ping和ssh”-等等什么?