Heim Web-Frontend js-Tutorial Eine kurze Analyse der JavaScript-Fehlerbehandlung und Stack-Tracing

Eine kurze Analyse der JavaScript-Fehlerbehandlung und Stack-Tracing

Nov 17, 2017 pm 01:27 PM
javascript js 追踪

Manchmal werden im Prozess unserer Code-Sammlung einige Details der Fehlerbehandlung und Stapelverfolgung ignoriert. Wenn Sie jedoch auf diese Details achten, sind sie beim Schreiben von Bibliotheken im Zusammenhang mit Tests oder Fehlerbehandlung sehr nützlich Diese Idee kann die Art und Weise, wie wir mit dem Stapel umgehen, erheblich verbessern. Wenn die Behauptung des Benutzers fehlschlägt, können wir dem Benutzer schnellere Informationen geben um nutzlose Daten zu löschen und sich nur auf nützliche Daten zu konzentrieren. Gleichzeitig kann Ihnen ein besseres Verständnis des Errors-Objekts und seiner zugehörigen Eigenschaften dabei helfen,

Fehler besser zu nutzen.

Wie das Der Aufrufstapel (der Funktion) funktioniert

Bevor wir über Fehler sprechen, müssen wir zunächst das Prinzip des Aufrufstapels (der Funktion) verstehen:

Wenn eine Funktion aufgerufen wird, wird sie an die Spitze verschoben Nachdem die Funktion abgeschlossen ist, wird sie von der Oberseite des Stapels entfernt.

Die Datenstruktur des Stapels ist rückwärts. First Out, bekannt als LIFO (Last In, First Out).

Zum Beispiel:

function c() {
    console.log('c');
}
function b() {
    console.log('b');
    c();
}
function a() {
    console.log('a');
    b();
}
a();
Nach dem Login kopieren


Im obigen Beispiel wird die Funktion a zur Laufzeit oben auf dem Stapel hinzugefügt. Dann, wenn Funktion b wird innerhalb von Funktion a aufgerufen, Funktion b wird an die Spitze des Stapels verschoben. Wenn Funktion c innerhalb von Funktion b aufgerufen wird, wird sie ebenfalls an die Spitze des Stapels verschoben Wenn Funktion c ausgeführt wird, enthält der Stapel a, b und c (in dieser Reihenfolge). Der Funktionsaufruf kehrt zu Funktion b zurück. Nachdem die Ausführung von Funktion b abgeschlossen ist, wird sie ebenfalls von der Oberseite des Stapels entfernt, und dann kehrt der Funktionsaufruf zu Funktion a zurück wird nach der Ausführung von der Oberseite des Stapels entfernt.

Um das Verhalten des Stapels in der Demo besser zu demonstrieren, können Sie die Konsolenverfolgung () verwenden, um die aktuellen Stapeldaten auf der Konsole auszugeben. Gleichzeitig müssen Sie die Ausgabestapeldaten der Reihe nach von oben nach unten lesen.

Das Ausführen des obigen Codes im REPL-Modus des Knotens führt zu der folgenden Ausgabe:

Wie Sie sehen können, enthält der Stapel bei der Ausgabe von Funktion c die Funktionen a, b und c.

Wenn Sie die aktuellen Stapeldaten in Funktion b danach ausgeben Funktion c ist abgeschlossen, Sie werden sehen, dass Funktion c von der Oberseite des Stapels entfernt wurde und der Stapel nur die Funktionen a und b enthält.
function c() {
    console.log('c');
    console.trace();
}
function b() {
    console.log('b');
    c();
}
function a() {
    console.log('a');
    b();
}
a();
Nach dem Login kopieren

Wie Sie sehen können, nachdem Funktion c abgeschlossen ist Beim Ausführen wurde es von der Oberseite des Stapels entfernt.
Trace
    at c (repl:3:9)
    at b (repl:3:1)
    at a (repl:3:1)
    at repl:1:1 // <-- For now feel free to ignore anything below this point, these are Node&#39;s internals
    at realRunInThisContextScript (vm.js:22:35)
    at sigintHandlersWrap (vm.js:98:12)
    at ContextifyScript.Script.runInThisContext (vm.js:24:12)
    at REPLServer.defaultEval (repl.js:313:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
Nach dem Login kopieren


Fehlerobjekt und Fehlerbehandlung

Wenn während der Ausführung des Programms ein Fehler auftritt, wird normalerweise ein Fehlerobjekt ausgelöst . Das Error-Objekt kann als vom benutzerdefinierten Fehlerobjekt geerbter Prototyp verwendet werden. Das

Error.prototype-Objekt enthält die folgenden Eigenschaften:

function c() {
    console.log(&#39;c&#39;);
}
function b() {
    console.log(&#39;b&#39;);
    c();
    console.trace();
}
function a() {
    console.log(&#39;a&#39;);
    b();
}
Nach dem Login kopieren
constructor – zeigt auf den Konstruktor der Instanz

Nachricht – Fehlermeldung
Trace
    at b (repl:4:9)
    at a (repl:3:1)
    at repl:1:1  // <-- For now feel free to ignore anything below this point, these are Node&#39;s internals
    at realRunInThisContextScript (vm.js:22:35)
    at sigintHandlersWrap (vm.js:98:12)
    at ContextifyScript.Script.runInThisContext (vm.js:24:12)
    at REPLServer.defaultEval (repl.js:313:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.onLine (repl.js:513:10)
Nach dem Login kopieren

Name – Fehlername (Typ)

Die oben genannten sind die Standardeigenschaften von Error.prototype. Darüber hinaus haben verschiedene Betriebsumgebungen ihre eigenen Besonderheiten Eigenschaften. In Umgebungen wie Node, Firefox, Chrome, Edge, IE 10+, Opera und Safari 6+ verfügt das Error-Objekt über eine Stack-Eigenschaft, die den Stack-Trace des Fehlers enthält Fehlerinstanz Der Stack-Trace enthält alle Stack-Strukturen seit dem Konstruktor.

Wenn Sie mehr über die spezifischen Eigenschaften des Error-Objekts erfahren möchten, können Sie diesen Artikel auf MDN lesen.

In Um einen ausgelösten Fehler abzufangen, muss try...catch verwendet werden, um den Code einzuschließen, der den Fehler verursachen könnte. Der Parameter von Catch ist die Fehlerinstanz, die aufgetreten ist geworfen.

Wie Java erlaubt auch JavaScript die Verwendung des Schlüsselworts „final“ nach try/catch. Nach der Fehlerbehandlung können Sie im „final“-Anweisungsblock einige Aufräumarbeiten durchführen.

Syntaktisch können Sie den Try-Anweisungsblock und andere verwenden. Es muss kein Catch-Anweisungsblock folgen, sondern ein Final-Anweisungsblock. Das bedeutet, dass es drei verschiedene Try-Anweisungsformen gibt:

versuchen...fangen

versuchen...endlich

versuchen...fangen...endlich

Try-Anweisung kann auch Try-Anweisung einbetten:

Sie können Try-Anweisungen auch in Catch einbetten oder schließlich:

Das ist wichtig zu beachten Wenn ein Fehler ausgelöst wird, können Sie anstelle eines Fehlerobjekts einfach einen einfachen Wert auslösen. Dies sieht zwar cool aus und ist zulässig, ist jedoch kein empfohlener Ansatz, insbesondere für Entwickler von Bibliotheken und Frameworks, die mit dem Code anderer Leute umgehen müssen , weil es keinen Standard gibt, auf den man sich beziehen kann, und es keine Möglichkeit gibt, zu wissen, was von den Benutzern empfangen wird. Sie können dem Benutzer nicht vertrauen, dass er ein Fehlerobjekt auslöst, da er dies möglicherweise nicht tut und einfach eine Zeichenfolge ausgibt oder Wert. Dies bedeutet auch, dass es schwierig ist, mit Stapelinformationen und anderen Metainformationen umzugehen. Zum Beispiel:

Wenn der Parameter vom Benutzer an die Funktion runWithoutThrowing übergeben wird Wenn ein Fehlerobjekt ausgelöst wird, kann der obige Code den Fehler normal erfassen. Wenn dann eine Zeichenfolge ausgelöst wird, wird Folgendes angezeigt: Habe einige Fragen:

function runWithoutThrowing(func) {
    try {
        func();
    } catch (e) {
        console.log(&#39;There was an error, but I will not throw it.&#39;);
        console.log(&#39;The error\&#39;s message was: &#39; + e.message)
    }
}
function funcThatThrowsString() {
    throw &#39;I am a String.&#39;;
}
runWithoutThrowing(funcThatThrowsString);
Nach dem Login kopieren

现在第二个 console.log 会输出undefined. 这看起来不是很重要, 但如果你需要确保 Error 对象有一个特定的属性或者用另一种方式来处理 Error 对象的特定属性(例如 Chai的throws断言的做法), 你就得做大量的工作来确保程序的正确运行.同时, 如果抛出的不是 Error 对象, 也就获取不到 stack 属性.

Errors 也可以被作为其它对象, 你也不必抛出它们, 这也是为什么大多数回调函数把 Errors 作为第一个参数的原因. 例如:

const fs = require(&#39;fs&#39;);
fs.readdir(&#39;/example/i-do-not-exist&#39;, function callback(err, dirs) {
    if (err instanceof Error) {
        // `readdir` will throw an error because that directory does not exist
        // We will now be able to use the error object passed by it in our callback function
        console.log(&#39;Error Message: &#39; + err.message);
        console.log(&#39;See? We can use Errors without using try statements.&#39;);
    } else {
        console.log(dirs);
    }
});
Nach dem Login kopieren

最后, Error 对象也可以用于 rejected promise, 这使得很容易处理 rejected promise:

new Promise(function(resolve, reject) {
    reject(new Error(&#39;The promise was rejected.&#39;));
}).then(function() {
    console.log(&#39;I am an error.&#39;);
}).catch(function(err) {
    if (err instanceof Error) {
        console.log(&#39;The promise was rejected with an error.&#39;);
        console.log(&#39;Error Message: &#39; + err.message);
    }
});
Nach dem Login kopieren

处理堆栈

这一节是针对支持 Error.captureStackTrace的运行环境, 例如Nodejs.

Error.captureStackTrace 的第一个参数是 object, 第二个可选参数是一个 function.Error.captureStackTrace 会捕获堆栈信息, 并在第一个参数中创建

stack 属性来存储捕获到的堆栈信息. 如果提供了第二个参数, 该函数将作为堆栈调用的终点. 因此, 捕获到的堆栈信息将只显示该函数调用之前的信息.

用下面的两个demo来解释一下. 第一个, 仅将捕获到的堆栈信息存于一个普通的对象之中:

const myObj = {};
function c() {
}
function b() {
    // Here we will store the current stack trace into myObj
    Error.captureStackTrace(myObj);
    c();
}
function a() {
    b();
}
// First we will call these functions
a();
// Now let&#39;s see what is the stack trace stored into myObj.stack
console.log(myObj.stack);
// This will print the following stack to the console:
//    at b (repl:3:7) <-- Since it was called inside B, the B call is the last entry in the stack
//    at a (repl:2:1)
//    at repl:1:1 <-- Node internals below this line
//    at realRunInThisContextScript (vm.js:22:35)
//    at sigintHandlersWrap (vm.js:98:12)
//    at ContextifyScript.Script.runInThisContext (vm.js:24:12)
//    at REPLServer.defaultEval (repl.js:313:29)
//    at bound (domain.js:280:14)
//    at REPLServer.runBound [as eval] (domain.js:293:12)
//    at REPLServer.onLine (repl.js:513:10)
Nach dem Login kopieren

从上面的示例可以看出, 首先调用函数 a(被压入堆栈), 然后在 a 里面调用函数 b(被压入堆栈且在a之上), 然后在 b 中捕获到当前的堆栈信息, 并将其存储到 myObj 中. 所以, 在控制台输出的堆栈信息中仅包含了 a和 b 的调用信息.

现在, 我们给 Error.captureStackTrace 传递一个函数作为第二个参数, 看下输出信息:

const myObj = {};
function d() {
    // Here we will store the current stack trace into myObj
    // This time we will hide all the frames after `b` and `b` itself
    Error.captureStackTrace(myObj, b);
}
function c() {
    d();
}
function b() {
    c();
}
function a() {
    b();
}
// First we will call these functions
a();
// Now let&#39;s see what is the stack trace stored into myObj.stack
console.log(myObj.stack);
 
// This will print the following stack to the console:
//    at a (repl:2:1) <-- As you can see here we only get frames before `b` was called
//    at repl:1:1 <-- Node internals below this line
//    at realRunInThisContextScript (vm.js:22:35)
//    at sigintHandlersWrap (vm.js:98:12)
//    at ContextifyScript.Script.runInThisContext (vm.js:24:12)
//    at REPLServer.defaultEval (repl.js:313:29)
//    at bound (domain.js:280:14)
//    at REPLServer.runBound [as eval] (domain.js:293:12)
//    at REPLServer.onLine (repl.js:513:10)
//    at emitOne (events.js:101:20)
Nach dem Login kopieren


当将函数 b 作为第二个参数传给 Error.captureStackTraceFunction 时, 输出的堆栈就只包含了函数 b 调用之前的信息(尽管 Error.captureStackTraceFunction 是在函数 d 中调用的), 这也就是为什么只在控制台输出了 a. 这样处理方式的好处就是用来隐藏一些与用户无关的内部实现细节.

感谢大家阅读本篇文章,之后也会给大家带来关于JS,关于前端的一些小技巧,希望大家共同探讨,一起进步。


相关推荐:

JavaScript和ECMAScript 之间的区别

JavaScript刷新页面location.reload()的用法

JavaScript中正则表达式的含义与使用

Das obige ist der detaillierte Inhalt vonEine kurze Analyse der JavaScript-Fehlerbehandlung und Stack-Tracing. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Crossplay haben?
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So implementieren Sie ein Online-Spracherkennungssystem mit WebSocket und JavaScript So implementieren Sie ein Online-Spracherkennungssystem mit WebSocket und JavaScript Dec 17, 2023 pm 02:54 PM

So implementieren Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem. Einführung: Mit der kontinuierlichen Weiterentwicklung der Technologie ist die Spracherkennungstechnologie zu einem wichtigen Bestandteil des Bereichs der künstlichen Intelligenz geworden. Das auf WebSocket und JavaScript basierende Online-Spracherkennungssystem zeichnet sich durch geringe Latenz, Echtzeit und plattformübergreifende Eigenschaften aus und hat sich zu einer weit verbreiteten Lösung entwickelt. In diesem Artikel wird erläutert, wie Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem implementieren.

Empfohlen: Ausgezeichnetes JS-Open-Source-Projekt zur Gesichtserkennung und -erkennung Empfohlen: Ausgezeichnetes JS-Open-Source-Projekt zur Gesichtserkennung und -erkennung Apr 03, 2024 am 11:55 AM

Die Technologie zur Gesichtserkennung und -erkennung ist bereits eine relativ ausgereifte und weit verbreitete Technologie. Derzeit ist JS die am weitesten verbreitete Internetanwendungssprache. Die Implementierung der Gesichtserkennung und -erkennung im Web-Frontend hat im Vergleich zur Back-End-Gesichtserkennung Vor- und Nachteile. Zu den Vorteilen gehören die Reduzierung der Netzwerkinteraktion und die Echtzeiterkennung, was die Wartezeit des Benutzers erheblich verkürzt und das Benutzererlebnis verbessert. Die Nachteile sind: Es ist durch die Größe des Modells begrenzt und auch die Genauigkeit ist begrenzt. Wie implementiert man mit js die Gesichtserkennung im Web? Um die Gesichtserkennung im Web zu implementieren, müssen Sie mit verwandten Programmiersprachen und -technologien wie JavaScript, HTML, CSS, WebRTC usw. vertraut sein. Gleichzeitig müssen Sie auch relevante Technologien für Computer Vision und künstliche Intelligenz beherrschen. Dies ist aufgrund des Designs der Webseite erwähnenswert

Wesentliche Tools für die Aktienanalyse: Lernen Sie die Schritte zum Zeichnen von Kerzendiagrammen mit PHP und JS Wesentliche Tools für die Aktienanalyse: Lernen Sie die Schritte zum Zeichnen von Kerzendiagrammen mit PHP und JS Dec 17, 2023 pm 06:55 PM

Wesentliche Tools für die Aktienanalyse: Lernen Sie die Schritte zum Zeichnen von Kerzendiagrammen in PHP und JS. Mit der rasanten Entwicklung des Internets und der Technologie ist der Aktienhandel für viele Anleger zu einer wichtigen Möglichkeit geworden. Die Aktienanalyse ist ein wichtiger Teil der Anlegerentscheidung, und Kerzendiagramme werden häufig in der technischen Analyse verwendet. Wenn Sie lernen, wie man Kerzendiagramme mit PHP und JS zeichnet, erhalten Anleger intuitivere Informationen, die ihnen helfen, bessere Entscheidungen zu treffen. Ein Candlestick-Chart ist ein technischer Chart, der Aktienkurse in Form von Candlesticks anzeigt. Es zeigt den Aktienkurs

WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen Dec 17, 2023 pm 05:30 PM

WebSocket und JavaScript: Schlüsseltechnologien zur Realisierung von Echtzeit-Überwachungssystemen Einführung: Mit der rasanten Entwicklung der Internet-Technologie wurden Echtzeit-Überwachungssysteme in verschiedenen Bereichen weit verbreitet eingesetzt. Eine der Schlüsseltechnologien zur Erzielung einer Echtzeitüberwachung ist die Kombination von WebSocket und JavaScript. In diesem Artikel wird die Anwendung von WebSocket und JavaScript in Echtzeitüberwachungssystemen vorgestellt, Codebeispiele gegeben und deren Implementierungsprinzipien ausführlich erläutert. 1. WebSocket-Technologie

Wie können Sie den genauen Standort Ihres Apple-Telefons verfolgen, wenn es verloren geht und ausgeschaltet ist? Wie können Sie den genauen Standort Ihres Apple-Telefons verfolgen, wenn es verloren geht und ausgeschaltet ist? Mar 08, 2024 pm 02:30 PM

Es ist auch möglich, ein Apple-Telefon wiederherzustellen, wenn es verloren geht und ausgeschaltet ist. Die Methode ist auch sehr einfach. Benutzer können sich zur Suche auf der offiziellen iCloud-Website anmelden, oder ein Freund, der ebenfalls ein Apple-Telefon verwendet, kann sein Telefon verwenden um nach Ihrem iPhone zu suchen. Wie kann man den genauen Standort eines Apple-Telefons verfolgen, wenn es verloren geht und ausgeschaltet ist? Antwort: Suchen Sie auf der offiziellen iCloud-Website oder leihen Sie sich das iPhone-Gerät einer anderen Person aus, um es zu finden. 1. Benutzer stellen fest, dass ihr Apple-Telefon verloren gegangen ist oder fehlt Es kann auch dann gefunden werden, wenn es ausgeschaltet ist. 2. Benutzer melden sich direkt auf der offiziellen iCloud-Website an, klicken auf „Mein iPhone suchen“ und geben unbedingt die richtige Kontonummer ein. 3. Stellen Sie sicher, dass Ihr Konto mit dem Konto des verlorenen Telefons übereinstimmt, damit Sie das Telefon wiederherstellen können. 4. Wenn das Telefon eingeschaltet und verbunden ist

Verwendung von JavaScript und WebSocket zur Implementierung eines Echtzeit-Online-Bestellsystems Verwendung von JavaScript und WebSocket zur Implementierung eines Echtzeit-Online-Bestellsystems Dec 17, 2023 pm 12:09 PM

Einführung in die Verwendung von JavaScript und WebSocket zur Implementierung eines Online-Bestellsystems in Echtzeit: Mit der Popularität des Internets und dem Fortschritt der Technologie haben immer mehr Restaurants damit begonnen, Online-Bestelldienste anzubieten. Um ein Echtzeit-Online-Bestellsystem zu implementieren, können wir JavaScript und WebSocket-Technologie verwenden. WebSocket ist ein Vollduplex-Kommunikationsprotokoll, das auf dem TCP-Protokoll basiert und eine bidirektionale Kommunikation zwischen Client und Server in Echtzeit realisieren kann. Im Echtzeit-Online-Bestellsystem, wenn der Benutzer Gerichte auswählt und eine Bestellung aufgibt

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Dec 17, 2023 pm 05:13 PM

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Einführung: Heutzutage ist die Genauigkeit von Wettervorhersagen für das tägliche Leben und die Entscheidungsfindung von großer Bedeutung. Mit der Weiterentwicklung der Technologie können wir genauere und zuverlässigere Wettervorhersagen liefern, indem wir Wetterdaten in Echtzeit erhalten. In diesem Artikel erfahren Sie, wie Sie mit JavaScript und WebSocket-Technologie ein effizientes Echtzeit-Wettervorhersagesystem aufbauen. In diesem Artikel wird der Implementierungsprozess anhand spezifischer Codebeispiele demonstriert. Wir

PHP- und JS-Entwicklungstipps: Beherrschen Sie die Methode zum Zeichnen von Aktienkerzendiagrammen PHP- und JS-Entwicklungstipps: Beherrschen Sie die Methode zum Zeichnen von Aktienkerzendiagrammen Dec 18, 2023 pm 03:39 PM

Mit der rasanten Entwicklung der Internetfinanzierung sind Aktieninvestitionen für immer mehr Menschen zur Wahl geworden. Im Aktienhandel sind Kerzendiagramme eine häufig verwendete Methode der technischen Analyse. Sie können den sich ändernden Trend der Aktienkurse anzeigen und Anlegern helfen, genauere Entscheidungen zu treffen. In diesem Artikel werden die Entwicklungskompetenzen von PHP und JS vorgestellt, der Leser wird zum Verständnis des Zeichnens von Aktienkerzendiagrammen geführt und es werden spezifische Codebeispiele bereitgestellt. 1. Aktien-Kerzendiagramme verstehen Bevor wir uns mit dem Zeichnen von Aktien-Kerzendiagrammen befassen, müssen wir zunächst verstehen, was ein Kerzendiagramm ist. Candlestick-Charts wurden von den Japanern entwickelt

See all articles