2016-06-29 6 views
0

Ich lade sqs.receiveMessage(receiveParams, function(err, data){}) innerhalb einer Endlosschleife auf. Aber es wurde überhaupt nicht ausgelöst.Kann keine Nachricht von SQS in Endlosschleife empfangen

var receiveParams = { 
    QueueUrl: queueUrl, 
    VisibilityTimeout: 40 
}; 

while (true) 
{ 
    console.log("before"); 
    setTimeout(function() { 
     sqs.receiveMessage(receiveParams, function(err,data){ 
      console.log("Calling"); 
      if (err) { 
       console.log(err); 
      } 
      else { 
       console.log(data); 
       if (data.Messages != null) 
       { 
        console.log("Executing my fuction"); 
        myFunction(); 
       } 
      } 
     }); 
    }, 10000); 

    console.log("after"); 
} 

Wenn ich sqs.receiveMessage() außerhalb der Schleife ausführen, funktioniert es gut. Ich weiß nicht, warum es in der Schleife nie aufgerufen wird. Ich vermute, dass etwas mit meinen Timeout-Einstellungen nicht stimmt. Weil meine Schleife ohne Zeitverzögerung "davor" und "danach" protokolliert. Irgendeine Hilfe?

Antwort

2

Ihr Code überflutet den Knotenereignisstapel mit unendlich vielen setTimeout Befehlen.

Das heißt, auf Code-Lauf spawn zuerst eine Aufgabe, um den sqs.receiveMessage Aufruf zu tun - was es eine Sekunde später tun wird. Bevor jedoch die erste Aufgabe ausgelöst wird, wird in der zweiten Iteration Ihrer while-Schleife erneut eine ähnliche Aufgabe erzeugt. Innerhalb eines Sekundenzeitrahmens werden Sie also tausend Aufgaben haben, die wahrscheinlich 1 Millisekunden auseinander liegen. Dies erklärt, warum Sie die Drucke sehen.

Der Grund, warum Sie keine korrekte Antwort von dem Dienst erhalten, könnte sein, dass es "Hochwasserschutz" aktiviert hat. Z.B. Wenn innerhalb einer bestimmten Zeit zu viele Anfragen von demselben Anrufer eingehen, wird der Anrufer für X Zeit ignoriert.

Sie könnten stattdessen setInterval verwenden. Siehe
https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval

setInterval
wiederholt eine Funktion aufruft oder ausführt, einen Code-Schnipsel, mit einer festen Zeitverzögerung zwischen jedem Anruf. Gibt eine Intervall-ID zurück.

Beispiel:

// repeat the call every 10seconds 
setInterval(function() { 
    sqs.receiveMessage(receiveParams, function(err,data){ 
     console.log("Calling"); 
     if (err) { 
      console.log(err); 
     } 
     else { 
      console.log(data); 
      if (data.Messages != null) 
      { 
       console.log("Executing my fuction"); 
       myFunction(); 
      } 
     } 
    }); 
}, 10000); 

Lassen Sie mich wissen, wie Sie mit ihm zu gehen. Gerne weiter helfen, falls erforderlich.

+0

Ihre Erklärung ist korrekt, aber eine 'async' Schleife könnte in meinem Fall eine bessere Lösung sein. –

+0

@LingboTang - Froh, dass die Erklärung hilft und schließlich zu einer noch besseren Lösung führt. –