【问题标题】:Conditionally executing a callback within an asynchronous function call in a for loop在 for 循环中的异步函数调用中有条件地执行回调
【发布时间】:2011-10-24 14:58:20
【问题描述】:

我正在开发一个函数,它遍历端口列表并在其中一个端口可用时调用其回调。我不想等待每个端口响应,而是想在所有端口上调用 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 都返回端口不可用时,我需要返回。

【问题讨论】:

    标签: javascript asynchronous node.js closures


    【解决方案1】:

    在函数之外初始化一些变量应该可以解决问题:

    // 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)
      }
    }
    

    【讨论】:

    • 当一个端口已经找到时,你也应该关闭其他端口。
    • 谢谢大卫,我想太多了。你的解决方案奏效了。代码可以在这里找到:github.com/baalexander/node-portscanner
    猜你喜欢
    • 2011-12-03
    • 2017-12-16
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    相关资源
    最近更新 更多