2017-04-04 5 views
1

Ich habe 1.211.434 IP-Adressen, die in geolocations konvertiert werden mussten. Ich habe eine API gefunden, die diese Frage mit der GET-Anfrage beantwortet. Aber die Sache ist, wenn ich eine for-Schleife benutze, kann ich die IP-Adresse nicht senden und die Beschreibung richtig erhalten.Knoten JS für Loop- und Array-Push

Majorly Ich habe zwei Fragen:

  1. Ich kann es einfach nicht ausgegeben, die ip_and_info Array und kann den Grund nicht finden. Kann mir jemand sagen, was schief gelaufen ist?

  2. Jetzt kann der Code, den ich schrieb, alle Informationen abrufen, die ich brauche, es gibt ungefähr 200 IP-Adressen in der test_ip.txt. Könnte es ein Problem geben, wenn ich versuche, all diese 1M IP-Adressen zu senden?

Gibt es jemanden, der mir einen Rat geben kann?

Sehr geschätzt.

Mein Code ist wie folgt:

fs = require('fs') 
async = require("async") 
http = require('http') 

ip_and_info = [] 
// getIPInfo("1.171.58.24") 


fs.readFile("../test_ips.txt", "utf-8", (err, content, printArr) => { 

    content = content.split("\n") 

    async.each(content, (ip) => { 
     content = getIPInfo(ip) 
     // console.log(ip) 
    }, (err) => { 
     if (err) { 
      console.log(err) 
     } else { 
      console.log(ip_and_info) 
     } 
    }) 

    // for (i in content) { 
    //  ((ip) => { 
    //   getIPInfo(ip) 
    //  })(content[i]) 
    // } 


}); 



function getIPInfo(ipAddress) { 

    options = { 
     host: 'freegeoip.net', 
     path: '/csv/' + ipAddress 
    } 

    request = http.get(options, function(response) { 
     // console.log('STATUS: ' + response.statusCode) 
     // console.log('HEADERS: ' + JSON.stringify(response.headers)) 

     // Buffer the body entirely for processing as a whole. 
     bodyChunks = [] 
     response.on('data', function(chunk) { 

      bodyChunks.push(chunk) 

     }).on('end', function() { 

      body = Buffer.concat(bodyChunks) 
      content = body.toString('ascii') 
      ip_and_info.push(content) 
      console.log(content) 
      return content 

     }) 
    }) 

    request.on('error', function(e) { 
     console.log('ERROR: ' + e.message) 
    }) 
} 

sehr willkommen!

+0

Es ist nicht das Problem, aber Ihr Code zum Opfer zu fallen [* The Horror of Implicit Globals *] (http://blog.niftysnippets.org/2008/03/horror-of-implicit-globals. html) * (das ist ein Beitrag auf meinem anämischen kleinen Blog) * - deklariere deine Variablen. –

+1

Sie benötigen Versprechen, wo Sie alle Ihre asynch Prozess in Array schieben und zusammen lösen –

+1

Ihr Code sollte nur leere Arrays drucken. Das liegt daran, dass Ihre Schleife fertig ausgeführt wird, bevor getIPInfo() aufgelöst wird. Wie @VinodLouis gesagt hat, können Sie dies mit Hilfe von Promises umgehen. Wenn Sie sich mit Versprechen nicht wohl fühlen, lassen Sie es mich wissen. Ich werde versuchen, eine Lösung vorzuschlagen. –

Antwort

-1

Ich denke, Ihr Problem könnte sein, dass Sie die 'Inhalt' Variable jede Schleife neu deklarieren, die Sie machen.

Vielleicht ändern Sie die Schleife so, dass Sie die Variable nicht jedes Mal zurücksetzen, wenn die Schleife ausgeführt wird. Ich hoffe, dass Ihr Problem behebt:

IPList = content.split("\n") 

    async.each(IPList, (ip) => { 
     IPGeoLocation = getIPInfo(ip) 
     console.log(IPGeoLocation) 
    }, (err) => { 

Was dies mit einer Million IP-Adressen zu tun, kann ich nicht großes Problem, so lange sehen, wie Sie eine anständige Menge an Speicherplatz auf Ihrem Computer haben. Vielleicht möchten Sie einen "Warte" -Aufruf hinzufügen, damit Sie den Server nicht so konsequent hämmern. Sie könnten dich blockieren! Ich würde 1 Sekunde zwischen jedem Anruf warten durch

Zugabe
sleep(1000); 

nach der IP bekommen.

1

Das Problem liegt in dieser Linie

content = getIPInfo(ip)

getIPInfo sollte eine Asynchron-Funktion sein. Eine Möglichkeit wäre, einen Rückruf an die Funktion zu senden und in der Funktion die Ausgabe im Callback zurückzugeben.

async.each(content, getIPInfo, (err) => { 
    if (err) { 
     console.log(err) 
    } else { 
     console.log(ip_and_info) 
    } 
}) 

Und in der getIPInfo Funktion

function getIPInfo(ipAddress, callback) { 
    ..... 
    ..... 
    ip_and_info.push(content) 
    callback(); 
} 

Auch anstelle async.each Verwendung async.eachSeries oder async.eachLimit sonst der Verwendung wird es versuchen Anfrage für alle 1.211.434 ips zu senden.

0

Verwenden Sie Versprechen.
Verwenden Sie die Schlüsselwörter let und const. Ernsthaft, implizite globale machen keinen Spaß.
Entscheiden Sie, ob ' oder " zu verwenden und bleiben Sie dabei, es ist viel besser lesbar.

Mit Versprechen, keine Notwendigkeit für asynchrone oder Ihre ip_and_info Variable.

'use strict'; 

const fs = require('fs'), 
    http = require('http'); 

fs.readFile('../test_ips.txt', 'utf-8', (err, content) => { 
    content = content.split('\n'); 

    Promise.resolve().then(() => { 
     return getAllIPInfo(content); 
    }).then((ipsInfos) => { 
     console.log('Info:' + ipsInfos); 
    }).catch((error) => { 
     console.error('Error: ' + error); 
    }); 
}); 

function getAllIPInfo(ipsAddress) { 
    return new Promise((resolve, reject) => { 
     let ipsInfo = []; 
     ipsAddress.reduce((previous, current, index, ips) => { 
      return previous.then(() => { 
       return getIPInfo(ips[index]).then((content) => { 
        ipsInfo.push(content); 
        return Promise.resolve(); 
       }); 
      }); 
     }, Promise.resolve()).then(() => { 
      resolve(ipsInfo); 
     }).catch((error) => { 
      reject(error); 
     }); 
    }); 
} 

function getIPInfo(ipAddress) { 
    return new Promise((resolve, reject) => { 
     let options = { 
      host: 'freegeoip.net', 
      path: '/csv/' + ipAddress 
     }; 

     http.get(options, function(response) { 
      // console.log('STATUS: ' + response.statusCode) 
      // console.log('HEADERS: ' + JSON.stringify(response.headers)) 

      // Buffer the body entirely for processing as a whole. 
      let bodyChunks = []; 

      response.on('data', function(chunk) { 
       bodyChunks.push(chunk); 
      }).on('end', function() { 
       let body = Buffer.concat(bodyChunks), 
        content = body.toString('ascii'); 

       resolve(content); 
      }); 
     }).on('error', function(e) { 
      console.log('ERROR: ' + e.message); 
      reject(e); 
     }); 
    }); 
} 
+0

Diese Lösung sendet eine Anfrage für alle 1.211.434 ips zusammen. Besser, wenn Sie Verspre- chensobjekte eines Blocks von ips erstellen und nach Abschluss zum nächsten Chunk wechseln. –

+0

@GolakSarangi: Aktualisiert, um die ips nacheinander aufzurufen – DrakaSAN