2016-08-16 4 views
0

Ich erstelle ein kleines Skript, um Callback besser zu verstehen.Callbacks verstehen

Von dem folgenden Skript war das erwartete Verhalten: "http.get wird ausgeführt und dauert im Durchschnitt 200 ms. Das For-Schleife" i "dauert im Durchschnitt 2500 ms. Bei 200 ms sollte der Prozess beendet werden Skript sollte aufgehört haben zu arbeiten. Warum ist es alle i Druck? Wenn ich dies besser zu verstehen, ich glaube, ich Rückruf verstehen.

var http = require("http"); 
var starttime = new Date(); 

//Function with Callback 
for (var j =0; j<10; j++){ 
    http.get({host : 'nba.com'}, function(res){ 
     console.log("Time Taken = ", new Date() - starttime, 'ms'); 

     process.exit(); 
    }).on('error', function(er){ 
     console.log('Got Error :', er.message); 
    }) 
} 

//Loop that exceeds callback trigger time 
for(var i=1; i<10000; i++){ 
    console.log(i); 
} 

console.log("Time Taken = ", new Date() - starttime, 'ms'); 
+0

Die for-Schleife ist synchron und der darin enthaltene Code ist asynchron. Es läuft durch die for-Schleife, die den get async Get Call auslöst. Die For-Schleife endet, bevor die On-Callbacks ausgelöst werden. Es gibt viele Dokumente und Beispiele im Internet, um zu veranschaulichen, wie async funktioniert. – bryanmac

+0

Danke bryanmac. Ich werde sie überprüfen. Es ist jetzt klar wie Wolke. – PatrickJames

Antwort

3

Javascript in node.js ist single threaded und I/O ist ereignisgesteuert mit Eine Ereigniswarteschlange So können Ihre asynchronen Callbacks, die die Beendigung der HTTP-Anforderungen signalisieren, erst ausgeführt werden, wenn der ursprüngliche Thread von Javascript beendet wurde, und die Steuerung an das System zurückgeben, wo sie das nächste Ereignis aus der Ereigniswarteschlange abrufen kann Er http Anfrage.

Als solche wird Ihre for Schleife vollständig ausgeführt, bevor HTTP-Antworten verarbeitet werden können.

Hier ist der Schritt für Schritt:

  1. Ihre erste for Schleife läuft und sendet 10 HTTP-Anfragen.
  2. Diese HTTP-Anforderungen werden im Hintergrund mithilfe von asynchronem Netzwerk ausgeführt. Wenn einer von ihnen abgeschlossen ist und eine Antwort hat, setzt das HTTP-Modul ein Ereignis in die Javascript-Ereigniswarteschlange und es wird der Job des JS-Interpreters sein, dieses Ereignis aus der Ereigniswarteschlange zu ziehen, wenn es mit seinen anderen Aktivitäten fertig ist.
  3. Ihre zweite for-Schleife wird vollständig ausgeführt, und alle i-Werte werden an die Konsole ausgegeben.
  4. Ihr Skript wird beendet.
  5. Der JS-Interpreter überprüft dann die Ereigniswarteschlange, um festzustellen, ob ausstehende Ereignisse vorliegen. In diesem Fall wird es einige http-Response-Ereignisse geben. Der JS-Interpreter zieht das älteste Ereignis aus der Ereigniswarteschlange und ruft den damit verbundenen Rückruf auf.
  6. Wenn dieser Rückruf abgeschlossen ist, wird das nächste Ereignis aus der Ereigniswarteschlange gezogen und der Prozess wird fortgesetzt, bis die Ereigniswarteschlange leer ist.
  7. Wenn einer Ihrer Callbacks process.exit() aufruft, werden die verbleibenden Callbacks kurzgeschlossen und der Prozess sofort beendet.

Während diese andere Antwort für den Browser geschrieben wurde, die ereignisgesteuerte, Single-Threaded-Konzept ist das gleiche, wie es in node.js ist so diese andere Antwort kann noch einige Dinge für Sie erklären: How does JavaScript handle AJAX responses in the background?

+0

Danke Jfiend00. Das erklärt es deutlich. Die Sache, die ich für Netzwerk oder I/O vergessen habe, ist Async, während die CPU aufgrund von Singlethread synchronisiert wird. For-Schleife ist CPU-bezogen und keine E/A. Macht Sinn. – PatrickJames