Werden Ausnahmen in lambdas in javascript / node.js abgefangen?

8

Ich habe einen node.js-Server, mit dem ich Ausnahmen behandeln kann, ohne abzustürzen, und ich habe Code wie den folgenden. Was ich wissen möchte, mit all den ereignisgesteuerten Großartigkeiten und Rückrufen und Lambdas und all dem, werden meine Ausnahmen immer noch von meinem Haupteinstiegspunkt erfasst werden?

%Vor%

Danke

    
Chris 22.02.2011, 21:47
quelle

3 Antworten

8

Es hängt vom Kontrollfluss ab. Node.js legt Wert darauf, asynchron zu sein, und einer der Hauptnachteile von asynchronicity ist, dass der Code nicht in einer Weise fließt, die Sie möglicherweise mit einer synchronisierten Sprache gewohnt sind.

In einer synchronen Sprache wird der Aufrufer gesperrt, während eine Funktion auf einige Daten wartet. Dies macht den Programmierer Job ziemlich einfach, weil sie garantiert werden kann, dass, wenn die Funktion, die auf Daten wartet, gibt es Daten für den Aufrufer zu konsumieren.

Es ist das genaue Gegenteil in einer asynchronen Sprache oder mit nicht blockierenden E / A. In diesem Fall ist der Anrufer für die Dauer des Funktionsaufrufs gesperrt, jedoch müssen die Funktionen nicht warten, bis Daten oder E / A abgeschlossen sind, bevor sie zurückgeliefert werden. Dies macht die Dinge etwas schwieriger für den Programmierer, denn wenn ein Funktionsaufruf zurückkommt, gibt es keine Garantien darüber, ob Daten verfügbar sind. Nicht-blockierende E / A impliziert daher typischerweise Rückruffunktionen, die aufgerufen werden, wenn Daten verfügbar sind, um darauf zu reagieren.

try/catch Blöcke arbeiten mit dem Aufruf-Stack. Das heißt, wenn eine Ausnahme ausgelöst wird, wird die Laufzeit den Aufrufstapel auflösen, bis ein catch -Block gefunden wird, der den Aufruf umgibt, der die Ausnahme ausgelöst hat. Da http.get jedoch ein nicht blockierender Aufruf ist, wird er sofort nach der Registrierung einiger Callbacks beendet und die Verarbeitung wird fortgesetzt. Die Callbacks werden in einem separaten "Thread" aufgerufen und daher sind die Aufrufe nicht im ursprünglichen try/catch -Block verschachtelt.

Ein Diagramm würde mir wirklich helfen, die Dinge hier zu erklären, aber leider habe ich keins für mich verfügbar.

    
Bryan Kyle 22.02.2011, 21:48
quelle
2

Der Fehlerbehandlungsstil für die Standardbibliothek node.js besteht darin, denselben Rückruf aufzurufen, aber ein erstes Argument, das den Fehler nicht null darstellt, zu übergeben. Wenn Sie außergewöhnliche Bedingungen in Ihrem asynchronen Code haben, bewahren Sie sie in diesem Format auf.

Ein throw würde die Aufruferkette hinaufklettern, die normalerweise nicht weiß, was Callbacks tun (zum Beispiel ist es dem tcp-Layer egal, dass seine Daten als http geparst werden). Throwable Exceptions sind schlecht geeignet für asynchrone Programmierung.

    
Tobu 22.02.2011 22:52
quelle
2

In Ihrem Beispielcode wird keine der potenziellen Ausnahmen, die aus dem http.get-Callback ausgelöst werden, in Ihrem catch-Block landen. Der Stapel des Callbacks wird aus der Ereignisschleife des Knotens erstellt, wenn Daten zum Lesen verfügbar sind.

Es gibt eine Möglichkeit, nicht erfasste Ausnahmen im Knoten einzufangen:

%Vor%

Dies wird für Ihr Beispiel funktionieren, abhängig davon, wo die Ausnahme ist.

Das Problem ist, dass nicht abgefangene Ausnahmen die inneren Vorgänge des Knotens auf überraschende Weise entwirren können, also wollen Sie sich wirklich nicht darauf verlassen. Die einzige zuverlässige Möglichkeit, alle möglichen Ausnahmen so zu erfassen, dass Sie mit ihnen umgehen können, besteht darin, einen Versuch / Fang um jeden Eintrittspunkt aus der Ereignisschleife zu setzen.

Das hört sich ziemlich langweilig an, ist aber normalerweise nicht so schlimm. In Ihrem Beispielprogramm verwenden Sie die API des Knotens für HTTP-Anfragen, die immer noch eine sehr untergeordnete Schnittstelle ist. Für die meisten Dinge möchten Sie diese Ausnahmebefehlsfunktion einmal einpacken und als Bibliothek verwenden.

    
Matt Ranney 01.03.2011 07:47
quelle

Tags und Links