2016-07-06 3 views
0

現在、NodeJSの使用方法を学習しており、この比較的単純な関数を一定の間隔で実行するよう書いています。この機能の目的は、新しく作成されたドロップレットを取得し、IPアドレスを更新することです。NodeJS配列の予期しない動作

router.newDroplets = setInterval(function() { 

    Server.find().then(function(svrs) { 
     for (var i = 0; i < svrs.length; i++) { 
      if (svrs[i].status == "Creating") { 
       library.getDropletById(svrs[i].serverid).then(function(svr) { 
        if (svr.droplet) { 
         for (var j = 0; j < svr.droplet.networks.v4.length; j++) { 
          if(svr.droplet.networks.v4[j].type == 'public') { 
           var ip_address = svr.droplet.networks.v4[j].ip_address; 
           console.log(ip_address); 

           Server.update({serverid: svr.droplet.id}, {ipaddress: ip_address, status: "Online"}, function(error, n) { 
            if (error) console.log(error); 
            else console.log(n); 
           }); 
          } 
         } 
        } else if (svr.id) { 
         // NOTE THIS LINE 
         console.log(svrs); 
        } 

       }, function() { 

       }); 
      } 
     } 
    }, function() { 

    }); 

}, 2500); 

特有の振る舞いは、上に記された行です。

console.log(svrs)を使用すると、MongoDBのサーバーコレクションにJSONドキュメントの配列が取得されます。しかし、console.log(svrs[i])を使用すると、undefinedがコンソールに記録されます。これは、私がvar i = 0;をforループの外に宣言しても起こります。なぜこのようなことが起こり、どうすればsvrs[i]にアクセスできますか?

+0

ような何かを試すことができArray.prototype.forEach

を使用するようにコードを変換することができ、私= 0; forループの外側で、 'for'ループは? –

+0

約束を正しく使用し、そのようなスパゲティコード(ネストされた約束)を書いてはいけません。 – undefined

+0

あなたは 'i'を記録しようとしましたか? –

答えて

2

約束の仕組みは、約束チェーンが非同期で実行されることです。コードが実行されるまでに、isvrs.lengthに等しいので、svrs[i]undefinedになります。これは、thenコールバックが呼び出される前に、forループが完全に実行されるためです。あなたが `これは私がVARを宣言する場合でも発生ですから、

svrs.forEach(function(svrInstance, i) { 
    if (svrInstance.status == "Creating") { 
    library.getDropletById(svrInstance.serverid).then(function(svr) { 
     if (svr.droplet) { 
     ... 
     } else if (svr.id) { 
     console.log(svrs[i]); 
     } 
    }); 
    } 
}); 
+0

あなたの説明と提案に感謝します。私は決して 'then'コールバックは' for'ループがループを終了した後にのみ呼び出されることは知らなかった。 –