节点脚本等待套接字事件触发,然后再进行下一次迭代

时间:2019-01-16 10:48:20

标签: node.js promise

具有以下返回的节点脚本

enter image description here

但是假装是要得到: 正在连线... 成功 插座关闭 正在连线... 成功 插座关闭 正在连线... 成功 插座关闭 正在连线... 成功 插座关闭

按该顺序。强制foreach在继续下一次迭代之前等待事件触发。

var net = require('net');
var client = new net.Socket();
const fs = require('fs');


var serverPingList = [
  {
    port:'80',
    domain:'domainexample'
  },
  {
    port:'8089',
    domain:'domainexample'
  },
  {
    port:'80',
    domain:'domainexample'
  },
  {
    port:'80',
    domain:'domainexample'
  },
  {
    port:'80',
    domain:'domainexample'
  },
]

serverPingList.forEach(function(server){

  pingPlatforms(server).then(function(result){
     console.log(result);
  }, function(err){
     console.log(err);
  });

})

function pingPlatforms(server){
  return new Promise(function(resolve, reject){
    var logInit = `server ${server.domain} and port ${server.port} Connecting...`
    var log;
    fs.appendFile('ping.log', logInit + '\n', (err) => {
        if(err)
          console.log('Unable to append to server.log.');
    });

    //console.log(server.port);
    //console.log(server.domain);
    console.log('Connecting...')

    //https://stackoverflow.com/questions/8588689/node-js-socket-io-client-connect-failed-connect-error-event
    //https://nodejs.org/api/net.html#net_socket_connect
    var socket = client.connect(server.port, server.domain);
    //var socket = ns_news.socket;

    //the ping failed
    socket.on('error', function(){
        var now = new Date().toString();
        log = `${now}: server ${server.domain} and port ${server.port} Connection Failed`;
        fs.appendFile('ping.log', log + '\n', (err) => {
            if(err)
              console.log('Unable to append to ping.log.');
        });
        resolve('success');
        //client.destroy();
    });
    // the ping is successful
    socket.on('connect', function(){
        console.log('Connected');

        var now = new Date().toString();
        log = `${now}: server ${server.domain} and port ${server.port} Connection Successful`;
        fs.appendFile('ping.log', log + '\n', (err) => {
            if(err)
              console.log('Unable to append to ping.log.');
        });
        resolve('success');
        //client.destroy();
    });

    socket.on('disconnect', function () {
      console.log('Disconnected');
      reject('disconnected');
    });
    socket.on('close', function () {
      console.log('socket closed');
      //client.destroy();
    });
  });
}

3 个答案:

答案 0 :(得分:1)

之所以会这样,是因为您使用了异步编程,在这种情况下是Promises。也许下面的示例可以使它更加清楚。

x = new Promise((res,rej) => {
  console.log("a");
  res();
  console.log("b");
})
x.then(() => console.log("c"));
console.log("d");
// a
// b
// d
// c

答案 1 :(得分:1)

本能地,我将删除promise,并使用async.eachSeries函数来链接您的ping。

这是未经测试的摘录,摘录自您的代码:

var net = require('net');
var client = new net.Socket();
const fs = require('fs');
const async = require("async");

var serverPingList = [
  {
    port:'80',
    domain:'domainexample'
  },
  {
    port:'8089',
    domain:'domainexample'
  },
  {
    port:'80',
    domain:'domainexample'
  },
  {
    port:'80',
    domain:'domainexample'
  },
  {
    port:'80',
    domain:'domainexample'
  },
]

async.eachSeries(serverPingList, function(server, callback){

  pingPlatforms(server, function(err){
    if(err){
      console.log("Error on pinging server", server.domain, err);
    }else{
      console.log("Success on pinging server",server.domain);
    }
    return callback();
  });
}, function(){
  console.log("All pings have been sent");
});

function pingPlatforms(server, cb){
  var logInit = `server ${server.domain} and port ${server.port} Connecting...`
  var log;
  fs.appendFile('ping.log', logInit + '\n', (err) => {
      if(err)
        console.log('Unable to append to server.log.');
  });

  //console.log(server.port);
  //console.log(server.domain);
  console.log('Connecting...')

  //https://stackoverflow.com/questions/8588689/node-js-socket-io-client-connect-failed-connect-error-event
  //https://nodejs.org/api/net.html#net_socket_connect
  var socket = client.connect(server.port, server.domain);
  //var socket = ns_news.socket;

  //the ping failed
  socket.on('error', function(){
      var now = new Date().toString();
      log = `${now}: server ${server.domain} and port ${server.port} Connection Failed`;
      fs.appendFile('ping.log', log + '\n', (err) => {
          if(err)
            console.log('Unable to append to ping.log.');
      });
      cb(null);
      //client.destroy();
  });
  // the ping is successful
  socket.on('connect', function(){
      console.log('Connected');

      var now = new Date().toString();
      log = `${now}: server ${server.domain} and port ${server.port} Connection Successful`;
      fs.appendFile('ping.log', log + '\n', (err) => {
          if(err)
            console.log('Unable to append to ping.log.');
      });
      cb(null);
      //client.destroy();
  });

  socket.on('disconnect', function () {
    console.log('Disconnected');
    cb("Error");
  });
  socket.on('close', function () {
    console.log('socket closed');
    //client.destroy();
  });
}

答案 2 :(得分:0)

通过按承诺终止或拒绝时,仅使用array的pop方法停止使用forEach来进行预期的工作,以便在下一次迭代时再次调用该函数(到目前为止必须有更好的方法来执行此操作。) )。感谢@Nikita Malyschkin和@MadWard提供的答案,但回调给我带来了@MadWard解决方案的困惑,并且没有返回@Nikita答案所想的那是我的问题...如何使用promise强制foreach周期进行同步(因为节点是异步的)。

Public Sub testpublic()
    MsgBox (test)
End Sub