2017-01-22 2 views
0

Ich habe einen Bot für Discord geschrieben, den ich aufgrund mehrerer asynchroner Antworten als fehlerhaft befunden habe. Es scheint nur 8 Anfragen zu machen und ignoriert die anderen.Nodejs mehrere Async-Anfragen scheitern sofort

Lauf Auszug aus dem Code:

/*Required modules 
    npm install request //used because it supports HTTPS 
    npm install cheerio 
*/ 
var request = require('request'); 
var cheerio = require('cheerio'); 

var ids = [ 
     "16286", 
     "16296", 
     "16284", 
     "15563", 
     "15964", 
     "15123", 
     "15592", 
     "868", 
     "15626", 
     "15627", 
     "339", 
     "350" 
    ]; 

var print = ""; 
var count = 0; 
for(var x=0;x<ids.length;x++) { 
    request({uri: "https://www.futbin.com" + "/17/player/"+ids[x], gzip: true}, function(error, response, full) { 
     let $ = cheerio.load(full); 
     var bins = $('.lowest_bin_next_tr'); 
     var header = $('.player_header').text().trim().split("-"); 
     console.log(header); 
     if(header != '') { 
     print += header[1].trim() + ", " + header[0] + "OVR " + $('.pcdisplay-pos').text().trim() + "\r\n"; 
     print += "**PS4:** " + $('#pslbin').text().slice(0, -1) + ", " + bins.eq(0).text().split("d")[1].trim() + ", " + bins.eq(1).text().split("d")[1].trim() + " " + $('.lowest_bin_updated_tr_ps4').text().trim().substring(8, this.length) + "\r\n"; 
     print += "**XBOX:** " + $('#xboxlbin').text().slice(0, -1) + ", " + bins.eq(4).text().split("d")[1].trim() + ", " + bins.eq(5).text().split("d")[1].trim() + " " + $('.lowest_bin_updated_tr_xb1').text().trim().substring(8, this.length) + "\r\n"; "\r\n"; 
     } 
     if(++count == ids.length) 
      callback(print); 
    }); 
} 

4 Anfragen sofort fehlschlagen, da 12-IDs sind. Warum erfüllt das nur 8 Anfragen?

+0

versuchen, den Fehler console.log und prüfen, warum werden die Anforderungen –

+0

der Host-Server andernfalls könnte Ihr Schnellfeuer 12 Anfragen als Denial-of-Service oder Rate Limiting Verletzung sehen. Sie müssen sich die genauen Fehler und möglicherweise die Netzwerk-Trace ansehen, um genau zu sehen, was die Fehler sind. Sie möchten vielleicht auch wissen, dass Ihre Anfragen in beliebiger Reihenfolge ankommen können, so dass die Reihenfolge, in der Sie sie in der 'print' -Variable erhalten, zufällig sein kann (abhängig vom spezifischen Verhalten des Host-Servers). – jfriend00

Antwort

0

Also, wenn ich Ihren Code ausführen, die ersten vier Antworten zurück eine leere header Variable erstellen. Das Ergebnis von:

$('.player_header').text().trim().split("-"); 

ist eine leere Zeichenfolge.

Aber jedes Mal, wenn ich es laufe, bekomme ich vier verschiedene, die leer sind. Ich denke, das ist eine Art serverseitiges Problem, wenn Sie 12 schnelle Feueranfragen senden.

In einem Test, wenn ich die Anfragen auf eine Anfrage pro Sekunde verlangsamen, melden alle 12 Daten. Dies ist definitiv ein serverseitiges Problem, bei dem es nicht gefällt, so viele Anfragen gleichzeitig zu erhalten.

Hier ist ein Beispiel für Testcode, der die Anforderungen auf einen pro Sekunde verlangsamt, die gut funktionieren. Ich bin nicht darauf hindeutet, diesen Produktionscode ist, aber ich wollte Ihnen den Code zeigen, dass eine Anfrage einmal pro Sekunde macht das gelingt:

/*Required modules 
    npm install request //used because it supports HTTPS 
    npm install cheerio 
*/ 
var request = require('request'); 
var cheerio = require('cheerio'); 

var ids = [ 
     "16286", 
     "16296", 
     "16284", 
     "15563", 
     "15964", 
     "15123", 
     "15592", 
     "868", 
     "15626", 
     "15627", 
     "339", 
     "350" 
    ]; 

var print = ""; 
var count = 0; 
ids.forEach(function(id, x) { 
    setTimeout(() => { 
     request({uri: "https://www.futbin.com" + "/17/player/"+id, gzip: true}, function(error, response, full) { 
      if (error) { 
       console.log(error); 
      } else { 
       let $ = cheerio.load(full); 
       var bins = $('.lowest_bin_next_tr'); 
       console.log(`header data [${id}]`, `"${$('.player_header').text().trim()}"`); 
       var header = $('.player_header').text().trim().split("-"); 
       if(header != '') { 
        print += header[1].trim() + ", " + header[0] + "OVR " + $('.pcdisplay-pos').text().trim() + "\r\n"; 
        print += "**PS4:** " + $('#pslbin').text().slice(0, -1) + ", " + bins.eq(0).text().split("d")[1].trim() + ", " + bins.eq(1).text().split("d")[1].trim() + " " + $('.lowest_bin_updated_tr_ps4').text().trim().substring(8, this.length) + "\r\n"; 
        print += "**XBOX:** " + $('#xboxlbin').text().slice(0, -1) + ", " + bins.eq(4).text().split("d")[1].trim() + ", " + bins.eq(5).text().split("d")[1].trim() + " " + $('.lowest_bin_updated_tr_xb1').text().trim().substring(8, this.length) + "\r\n"; "\r\n"; 
       } 
       if(++count == ids.length) 
        callback(print); 
      } 
     }); 
    }, x * 1000); 
}); 

function callback(data) { 
    console.log(data); 
} 

FYI, es funktioniert auch, wenn ich sie (eine Anfrage im Flug streng serialisiert bei zur Zeit) wie folgt aus:

/*Required modules 
    npm install request //used because it supports HTTPS 
    npm install cheerio 
*/ 
var Promise = require('bluebird'); 
var request = Promise.promisify(require('request'), {multiArgs: true}); 
var cheerio = require('cheerio'); 



var ids = [ 
     "16286", 
     "16296", 
     "16284", 
     "15563", 
     "15964", 
     "15123", 
     "15592", 
     "868", 
     "15626", 
     "15627", 
     "339", 
     "350" 
    ]; 

Promise.mapSeries(ids, function(id) { 
    return request({uri: "https://www.futbin.com" + "/17/player/"+id, gzip: true}).then(function(data) { 
     var response = data[0]; 
     var full = data[1]; 
     let $ = cheerio.load(full); 
     var bins = $('.lowest_bin_next_tr'); 
     console.log(`header data [${id}]`, `"${$('.player_header').text().trim()}"`); 
     var header = $('.player_header').text().trim().split("-"); 
     let print = ""; 
     if(header != '') { 
      print += header[1].trim() + ", " + header[0] + "OVR " + $('.pcdisplay-pos').text().trim() + "\r\n"; 
      print += "**PS4:** " + $('#pslbin').text().slice(0, -1) + ", " + bins.eq(0).text().split("d")[1].trim() + ", " + bins.eq(1).text().split("d")[1].trim() + " " + $('.lowest_bin_updated_tr_ps4').text().trim().substring(8, this.length) + "\r\n"; 
      print += "**XBOX:** " + $('#xboxlbin').text().slice(0, -1) + ", " + bins.eq(4).text().split("d")[1].trim() + ", " + bins.eq(5).text().split("d")[1].trim() + " " + $('.lowest_bin_updated_tr_xb1').text().trim().substring(8, this.length) + "\r\n"; "\r\n"; 
     } 
     return print; 
    }); 
}).then(function(results) { 
    console.log(results); 
});  
+0

@ inuyasha555 - Zu Ihrer Information, es funktioniert auch, wenn ich die Anfragen streng auf nur einen im Flug zu einer Zeit serialisieren (zweiter Block des Codes in meiner Antwort). Dieses zweite Schema behält auch die Reihenfolge der Antworten bei, die mit der Reihenfolge der Anforderungen übereinstimmen. – jfriend00

1
'strict mode'; 
var async = require('async'), 
request = require('request'); 

var cheerio = require('cheerio'); 

var ids = [ 
    "16286", 
    "16296", 
    "16284", 
    "15563", 
    "15964", 
    "15123", 
    "15592", 
    "868", 
    "15626", 
    "15627", 
    "339", 
    "350" 
]; 

var print = ""; 

async.eachSeries(ids , idsIteration , finishIteration); 

function idsIteration(id , callBack){ 
    processId(id , callBack); 
} 


function processId(id , cb){ 
    request({uri: "https://www.futbin.com" + "/17/player/"+id, gzip: true}, function(error, response, full) { 
    if(error){ 
     console.log('there was error entertainting request :' + error); 
     cb(error); 
    } 
    else { 
     var c = cheerio.load(full); 
     var bins = c('.lowest_bin_next_tr'); 
     var header = c('.player_header').text().trim().split("-"); 
     console.log(header); 
     if(header != '') { 
     print += header[1].trim() + ", " + header[0] + "OVR " + c('.pcdisplay-pos').text().trim() + "\r\n"; 
     print += "**PS4:** " + c('#pslbin').text().slice(0, -1) + ", " + bins.eq(0).text().split("d")[1].trim() + ", " + bins.eq(1).text().split("d")[1].trim() + " " + c('.lowest_bin_updated_tr_ps4').text().trim().substring(8, this.length) + "\r\n"; 
     print += "**XBOX:** " + c('#xboxlbin').text().slice(0, -1) + ", " + bins.eq(4).text().split("d")[1].trim() + ", " + bins.eq(5).text().split("d")[1].trim() + " " + c('.lowest_bin_updated_tr_xb1').text().trim().substring(8, this.length) + "\r\n"; "\r\n"; 
     } 
     cb(); 
     } 
    }); 
} 
function finishIteration(){ 
    console.log('all ids processed'); 
} 

OutPut auf meiner Konsole: enter image description here

+0

Und warum genau wird das Problem behoben? – jfriend00

+0

das spült nicht die Anfragen und es ist etwas wie Sie in Ihrer Antwort, aber auf andere Weise. @ jfriend00 –

+0

Du hast mich mit dem Begriff "Flush" verwechselt. Vielleicht, was Sie sagen wollen, ist, dass dies die Anfragen serialisieren wird, um nur jeweils einen im Flug zu haben? Hast du es versucht, um zu sehen, ob es funktioniert? – jfriend00