2011-08-11 11 views
3

私は、ポートのリストを反復処理し、そのポートの1つが利用可能になるとそのコールバックを呼び出す関数を作成しています。各ポートの応答を待つ代わりに、私はすべてのポートでcheckPortStatus関数を呼び出して、最初のポートが利用可能な状態に戻るときに戻りたいと思います。forループ内の非同期関数呼び出し内で条件付きでコールバックを実行

ここでのサンプルコードでは、Node.jsの中で実行可能です:

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

つの質問:私は一度だけコールバックを呼び出すにはどうすればよい

  1. コードを実行しているの

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

    結果?私は返すことに合っている最初のポートだけを必要とします。

  2. すべての関数コールバックが返されたかどうかを確認するにはどうすればよいですか?この例では、すべてのcheckPortStatusがポートを使用不可として返すときに戻る必要があります。トリックを行う必要があり、関数の外にいくつかの変数を初期化する

答えて

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) 
    } 
} 
+0

ポートがすでに発見されたときは、他のポートを閉じる必要があります。 – TiansHUo

+0

Davidさん、ありがとうございました。ソリューションが機能しました。コードは次のURLにあります:https://github.com/baalexander/node-portscanner – baalexander

関連する問題