Условно выполнить обратный вызов в асинхронном вызове функции в цикле for - PullRequest
3 голосов
/ 11 августа 2011

Я работаю над функцией, которая перебирает список портов и вызывает ее обратный вызов, как только один из портов становится доступным.Вместо того, чтобы ждать ответа каждого порта, я хотел бы вызвать функцию checkPortStatus на всех портах и ​​вернуться, когда первый порт вернется как доступный.

Вот пример кода, запускаемого в node.js:

    // Check if a port is open (in use) or closed (available)
    function checkPortStatus(port, callback) {
      // Simulates real world checking of response from port by returning
      // after a random time.
      setTimeout(function() {
        // Simulates a few closed ports
        if (port === 3005 || port === 3006 || port === 3007) {
          callback('closed')
        }
        // Simulates a few open ports
        else {
          callback('open')
        }
      }, Math.floor(Math.random() * 200))
    }

    // Calls callback once any available port is found
    function findAnAvailablePort(startPort, endPort, callback) {
      var check = function(port) {
        checkPortStatus(port, function(status) {
          // If a port is 'closed', it's considered available
          if (status === 'closed') {
            callback(port)
          }
        })
      }
      for (var port = startPort; port <= endPort; port++) {
        check(port)
      }
    }

    findAnAvailablePort(3000, 3010, function(port) {
      console.log('AVAILABLE PORT: ' + port)
    });

    // Don't exit Node, wait for a response
    setTimeout(function() { console.log('FIN') }, 5000)

Результаты выполнения кода:

AVAILABLE PORT: 3005
AVAILABLE PORT: 3007
AVAILABLE PORT: 3006

Два вопроса:

  1. Как я могу позвонить только один раз?Я хочу только первый порт, который соответствует, чтобы вернуться.
  2. Как проверить, все ли функции возвращены?В этом примере мне нужно вернуться, когда все checkPortStatus возвращают порты как недоступные.

1 Ответ

1 голос
/ 11 августа 2011

инициализация нескольких переменных за пределами функции должна помочь:

// Calls callback once any available port is found
var hasFoundPort = false;
var checkedPorts = 0;
function findAnAvailablePort(startPort, endPort, callback) {
  var check = function(port) {
    checkPortStatus(port, function(status) {
      checkedPorts++;
      // If a port is 'closed', it's considered available
      if (status === 'closed' && !hasFoundPort) { // only execute callback once
        callback(port)
        hasFoundPort = true;
      }
      if(checkedPorts == endPort - startPort + 1) // checked all ports
          console.log('finished checking');
    })
  }
  for (var port = startPort; port <= endPort; port++) {
    check(port)
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...