2016-08-23 2 views
1

Ich habe gerade einen Fehler behoben, bei dem ich Dateien mit readline gelesen und neu geschrieben habe und die Zeilen wurden in der falschen Reihenfolge geschrieben (es endete aufgrund eines asynchronen Aufrufs fs.write()).Node.js Readline-Leitung Ereignis Rückruf garantiert, vor dem nächsten Anruf zu beenden?

Aber eine Sache, die ich dachte, war geschah, dass die readlineline Ereignis in der richtigen Reihenfolge kommen in war, aber vielleicht für einige der Linien meine Callback-Funktion fertig war nach dem anderen line Ereignis behandelt worden war.

Um zu demonstrieren:

line1 event comes in 
line1 event finishes handling 
line2 event comes in //Takes a long time to process 
line3 event comes in 
line3 event finishes handling 
line2 event finished handling //And because it was after line3, gets written back after too 

Die endgültige Ausgabedatei von oben wäre wie:

line1 
line3 
line2 

ich keine solche Garantie in der Dokumentation zu sehen war und meine Tests scheinen, dass die Punkt oben ist nicht möglich, aber ich bin mir nicht sicher. Ist das obige Szenario mit readline möglich?

Antwort

3

NodeJS führt Ihren JavaScript-Code in einer einzelnen Ereignisschleife aus. Die JavaScript-Spezifikation ruft eine Jobwarteschlange auf. Das heißt, wenn Ihr Code auf Zeile2 reagiert, wird garantiert, dass er nicht auf Zeile3 antwortet, während er noch ausgeführt wird   — Wenn dieses Ereignis eintritt, während Ihr Code ausgeführt wird, wird der Job zum Aufrufen Ihres Callbacks in die Warteschlange gestellt, wartet jedoch die Jobwarteschlange, bis Sie fertig sind und die Ereignisschleife den nächsten Job in der Warteschlange übernehmen kann.

Offensichtlich gilt dies nur für synchronen Code, weil asynchrone Dinge (wie fs.write) nur einen Prozess starten , sie warten nicht darauf, es zu beenden; Completions sind Jobs, die zur Warteschlange hinzugefügt werden. So Rückrufe von asynchronen Aufrufen passieren kann, auch nach dem nächsten Ereignis kam in

ZB betrachten diesen Code:.

stream.on("line", function() { 
    // do a lot of synchronous work that may tie up the thread for a while 
}); 

Sie können sicher sein, dass Ihr Rückruf wird nicht für die Linie 3 bezeichnet werden, während es noch bearbeitet der Rückruf für Zeile 2.

Aber während der Verarbeitung der Rückruf für Zeile 2:

stream.on("line", function() { 
    // Code here IS guaranteed to run before we get called for line 3 
    callAnAsyncFunction(function(err, data) { 
     // Code here is NOT guaranteed to run before we get called for line 3 
    }); 
    // Code here IS guaranteed to run before we get called for line 3 
});