Multithreading in JavaScript

Imitieren von Multithreading in JavaScript

Eine proaktive ereignisgesteuerte Architektur ist wie der Hund zu fragen (wenn möglich wäre), "Wann wirst du den Ball werfen, wenn, was, wann?" Die Pseudo-Thread-Architektur wird mit Hilfe Timeouts. Der Pseudo-Thread ist das Ergebnis einer periodischen Funktion oder ein Objekt aufrufen, und die vollständige Umsetzung wird in den folgenden Quellcode gezeigt.

 Quelle: / client / scripts / Jaxson / Common.js Funktion ThreadObject () (this.obj = null; this.data = null; this.intervalId = null; this.isUsed = false;) ThreadObject.prototype.makeCall = function () ( if (typeof (this.obj) == "function") (this.obj (this.data);) else if (typeof (this.obj) == "object") (this.obj.run (this.data );)) = (var Thread threadObjects: new Array (), StartThread: function (obj, Daten, Zeit) (for (var c1 = 0; c1 <this.threadObjects.length; c1 + +) (if (! diesem . threadObjects [C1]. isUsed) (this.threadObjects [C1]. isUsed = true; this.threadObjects [C1]. data = data; this.threadObjects [C1]. = obj; this.threadObjects [C1]. intervalId = window.setInterval ( "Thread.threadObjects [" + c1 + "]. makeCall ()", time); return this.threadObjects [C1]. intervalId;)) throw new Error ( "konnte nicht gestartet werden ein Thread"); ), endThread: function (intervalId) (for (var c1 = 0; c1 <this.threadObjects.length; c1 + +) (if (this.threadObjects [C1]. intervalId == intervalId) (window.clearInterval (intervalId) ; this.threadObjects [C1]. isUsed = false;)))) function InitializeThreads (MaxThreads) (for (var c1 = 0; c1 <MaxThreads; c1 + +) (Thread.threadObjects.push (neu ThreadObject ()); )) InitializeThreads (30);

In der Quelle sind zwei Objekttypen definiert: ThreadObject und Faden. Die ThreadObject Typ wird benutzt, um das komische Threads zu verwalten, und Gewinde verwaltet das komische Fäden. Die InitializeThreads Funktion dient zur Einrichtung des Pseudo-Threading-Umgebung. Zu diesem Source-Code, ein Top-down-Ansatz zu erläutern wird.

Wenn der JavaScript-Datei mit den Pseudo-Thread-Architektur geladen wird, ist die InitializeThreads mit einem Parameter-Wert von 30 aufgerufen. InitializeThreads wird verwendet, um das Array der Pseudo-Threads, die genannt werden, zu initialisieren. Hard-Codierung zu einer Obergrenze von 30 Threads können wie ein schlechter Programmierstil erscheinen, aber es gibt einen Grund dafür. Um eine Pseudo-Thread erstellen Sie eine regelmäßige Veranstaltung, die bedeutet, dass Sie entweder die window.setInterval oder Verwendung window.setTimeout Methode. Aufruf einer dieser Methoden erfordert eine Funktions-Referenz oder ein Stück JavaScript-Code. Das Problem bei beiden Ansätzen ist, dass Sie den Quellcode zu serialisieren. Zum Beispiel vorstellen, dass Sie entweder der regelmäßigen Event-Methoden mit einer lokalen Objektreferenz inst nennen, wie die folgenden Quelltext dargestellt:

window.setInterval ( "CallFunction (inst)", 300);
  

Der Verweis auf die in der String-Puffer inst keine Bedeutung haben, denn wenn die periodische Timer-führt, lokale Variablen werden nicht in Zusammenhang stehen. Die Ausführung wird in einem Fehler. Ein anderer Weg, um die Funktion aufzurufen ist, serialisieren inst auf einen Puffer, aber den Nachteil, dass der Staat in die regelmäßige Veranstaltung genutzt wird nicht das gleiche Objekt Instanz hat, also wenn keine Änderungen vorgenommen werden, zwischen dem Aufruf der Funktion setInterval und Ablauf des Timers, werden sie nicht anwesend sein. Das einzige Mal, wenn inst ist gültig ist, wenn inst ist eine globale Variable. Als allgemeine Faustregel gilt, dass der sicherste Weg, einen Kontext-spezifische Methode machen Anruf über die Methoden setInterval oder setTimeout, um eine weltweite Referenz verwenden. Eine globale Referenz kann durch die dynamische Instanziierung Zufallsvariablen oder durch Verwendung eines Array-Index Fundstelle erstellt werden. Der Ansatz, den Thread gewählt wird, der Array-Index. InitializeThreads Die Funktion wird 30 weltweiten Referenzen ThreadObject initialisieren. Jeder ThreadObject Daten hat vier Mitglieder:

• obj: Referenzen das Objekt auszuführen. Die ThreadObject.makeCall Methode kann unterscheiden zwischen einer Funktion und Objekt. Wenn obj ist eine Funktion, dann obj genannt werden mit Hilfe einer Funktion Notation. Wenn obj ist ein Objekt-Instanz, dann ist die obj.run Methode aufgerufen wird.

• Daten: Referenzen die Daten als ein Zusammenhang, wenn obj ausgeführt werden.

• intervalId: Referenzen der zurückgegebene Wert von der window.setInterval Methode. Dieser Wert wird verwendet, um die regelmäßige Veranstaltung zu stoppen.

• isUsed: by Thread verwendet, um festzustellen, ob ein Array-Index derzeit verwendet wird. Wenn ein neues Thema starten will, die StartThread Methode sucht nach einem leeren Index, wo isUsed entspricht einem Wert, der falsch ist. Sobald ein Thread gestartet wurde, ist die isUsed Datenelement ein Wert zugewiesen, der wahren. Und wenn der Thread beendet wurde ausgeführt wird, wird die isUsed Datenelement ein Wert zugewiesen, der falsch wieder. Der Pseudo-Thread-Architektur ist in der Erklärung von DynamicIterator verwendet referenziert durch die Metadaten Navigationshilfen onmouseover und onmouseout Veranstaltungen. Wenn Sie die Maus bewegen, von einer Region in der HTML-Seite zur anderen, und die andere Region hat die onmouseover-Event durchgeführt, wird das Ereignis ausgelöst. Die onmouseover Ereignis wird ausgelöst, nur das erste Mal die Maus über das Ereignis, und dass die startIteration Methode genannt zu werden Ursachen, fordern Thread.startThread. Wenn die Maus bewegt sich aus der Metadaten Navigation Region ist der StopIteration Methode aufgerufen, ruft Thread.endThread. Die Umsetzung der startIteration StopIteration und ist wie folgt definiert.

 Quelle: / client / scripts / Jaxson / uimorphing.js (DynamicIterator)intervalId: 0, startIteration: function (Richtung) (this.intervalId = Thread.startThread (function (Richtung) (DynamicIterator.shiftArrayElements (Richtung);), Richtung, 500);), StopIteration: function () (Thread.endThread ( this.intervalId);)

Putting den übrigen Stücken des Kunden zusammen

Mehrere Male habe ich die DynamicIterator Umsetzung, die verwendet wird, um die Metadaten der Ergebnismenge navigieren verwiesen werden. Die Hauptaufgabe des DynamicIterator ist es, die Metadaten Navigations-Elemente zu laden, und wenn die einzelnen Elemente verwiesen wird, die wichtigsten Daten werden geladen. Ich erkläre die Umsetzung der DynamicIterator in Stücken, mit der folgenden Darstellung der Initialisierung der Navigationselemente.

 Quelle: / client / scripts / Jaxson / uimorphing.js var DynamicIterator = (lastElem: null, floatingIframe: null, parentRow: null, initialisieren: function (floatingIframeID, parentRowID) (this.floatingIframe = document.getElementById (floatingIframeID); this.parentRow = document.getElementById (parentRowID); this.doLayout (); this.getMoreRootElements (0);), doLayout: function () (this.floatingIframe.style.width = document.body.clientWidth - 4; this.floatingIframe.style. height = document.body.clientHeight - 104;) / / Andere Erklärungen ...);

 

Gehen wir zurück zum Beginn der "Umsetzung des HTML-Client"-Sektion, erinnert das Stück HTML-Code, umgesetzt body.onload der Veranstaltung, die dem lokalen Initialize-Funktion aufgerufen. Bei der Durchführung der Initialisierung ist die DynamicIterator.initialize-Methode aufgerufen. Calling DynamicIterator.initialize Querverweis wird der HTML-Elemente der Benutzeroberfläche mit der DynamicIterator Instanz.

DynamicIterator.initialize erwartet zwei HTML-Elemente der Benutzeroberfläche: Die schwimmende iframe (this.floatingIframe) und der Tabellenzeile (this.parentRow), dass die Navigations-Elemente enthält. DynamicIterator Bedürfnisse dieser beiden Elemente der Benutzeroberfläche, weil sie die Daten in der Navigations-Bereich deutlich Lasten. Nachdem die Elemente der Benutzeroberfläche haben, um die Daten Mitglieder zugeordnet wurde, ist die doLayout-Methode aufgerufen. Das Ziel ist es, die doLayout iframe die Größe so, dass sie die entsprechenden Client-Bereich abdeckt. Und der letzte Methodenaufruf in DynamicIterator.initialize ist die Berufung der getMoreRootElements Methode, die für das Laden der Metadaten, Navigations-Elemente zuständig ist. Im Rahmen der DynamicIterator ist die getMoreRootElements Methode als eine leere Funktion ähnlich der folgenden erklärt:

getMoreRootElements: function (Richtung) ()

Die leere Funktion ist ein Platzhalter, und es wird erwartet, dass der HTML-Code eine Implementierung erklären wird. Im Falle des HTML-Codes, getMoreRootElements ist wie folgt definiert.

 Quelle: / client / ajaxrest Artikel / Architektur / dynamiclist.html DynamicIterator.getMoreRootElements = function (Richtung) (if (Richtung == 0) (var = asynchrone FactoryHttp.getCachedAsynchronous (); asynchronous.settings = (onComplete: function (xmlhttp) (var arrTickers = new Array (); var Ticker = JSON.parse (xmlhttp.responseText); for (var c1 = 0; c1 <tickers.length; c1 + +) (arrTickers.push ((text: Ticker [c1], URL : "/ pyservices / Händler / geschichtlichen / Ticker /" + Ticker [C1]));) DynamicIterator.associateElements (arrTickers);)) asynchronous.get ( "/ pyservices / Händler / historisch-Ticker");))

Im Falle des HTML-Codes, die Ticker, dass repräsentieren die Metadaten, die zur Navigation durch die Anwendung einmal geladen werden. Metadaten können unbegrenzt sein, aber oft kann es zu einer festen Größe der Menge begrenzt werden, auch wenn das festgelegte Größe ist sehr groß. Mit Blick auf das Beispiel, wird jedes Stück von Metadaten einen Ticker, dass ein bis vier Buchstaben (im Durchschnitt) haben können. Wenn Sie diese Zahl multiplizieren mit 1000-Ticker, dann müssen Sie über 4KB Download-5KB von Daten (in diesem Zeitalter der Breitband - , das Herunterladen von 4KB-5KB ist trivial). Der Bestand Anwendung wird in den meisten 50-Ticker aufgrund technischer Einschränkungen zu ermöglichen, so dass alle von dem Ticker kann in einem Antrag heruntergeladen werden.

Im Falle unseres Beispiels, getMoreRootElements mit einer Richtung von 0 bedeutet, eine erste Reihe von Metadaten-Elemente herunterladen. Wie die Daten heruntergeladen wird, liegt in der Verantwortung der getMoreRootElements Umsetzung. Dieses Beispiel verwendet die asynchrone Klasse, und die Antwort als JSON-Array kodiert. Für jede Ticker gefunden, ein Objekt erstellt wird, wo der Ticker mit einer URL verbunden ist und in die arrTickers Array. Sobald die arrTickers Array wurde mit Elementen gefüllt, die DynamicIterator. AssociateElements Methode ist wie folgt aufgerufen.

 Quelle: / client / scripts / Jaxson / uimorphing.js (DynamicIterator)associateElements: function (arrElements) (this.arrElements = arrElements; this.shiftArrayElements (0);)

Die associateElements Methode macht zwei Dinge: ordnet die arrElements Referenz-Array und aktualisiert die Daten in der HTML-Seite mit dem shiftArrayElements Methode. Wenn der Benutzer den Mauszeiger über der linken oder rechten Pfeil, die Liste der Ticker Verschiebungen nach links oder rechts.

Die Index-Bewegung in der shiftArrayElements Methode enthalten sind. Der Aufrufer der Methode bietet die Richtung der Verschiebung mit einem positiven oder negativen Wert. Basierend auf den Richtungstasten Wert steigt der Index verschoben werden. Wenn der Index verschoben geht über die Grenzen des Feldes, dann mehr Metadaten-Elemente müssen gefunden werden. Die vollständige Umsetzung der shiftArrayElements ist wie folgt.

 Quelle: / client / scripts / Jaxson / uimorphing.js (DynamicIterator)shiftArrayElements: function (Offset) (this.currOffset = this.currOffset + offset; if (this.currOffset <0) (this.getMoreRootElements (-1); this.currOffset = 0;) else if ((+ this.currOffset dieser . parentRow.cells.length)> = this.arrElements.length) (this.getMoreRootElements (1); this.currOffset = this.arrElements.length - this.parentRow.cells.length;) for (var counter = 1; counter <(this.parentRow.cells.length - 1); counter + +) (this.parentRow.cells [counter]. innerHTML = this.arrElements [this.currOffset + counter - 1]. Text; this.parentRow.cells [ counter]. refElemInfo = this.arrElements [this.currOffset + counter - 1];))

Bei der Durchführung des shiftArrayElements, eine Berechnung der Verschiebung erfordert einen Test, um festzustellen, ob die Verschiebung ein Sprung über die Grenzen des Feldes verursacht. Wenn ein Sprung nach links oder rechts von der Array Grenzen passiert, dann die getMoreRootElements Methode aufgerufen wird, wenn die Richtung der Wert -1 oder 1 angibt Präfix Metadaten, um den Anfang des Feldes oder fügen Sie Daten zu Ende des Arrays, bzw.. Wenn die Verschiebung nicht dazu führt, ein Sprung über die Grenzen des Arrays, dann die einzelnen HTML-Bedienelemente sind neu gezeichnet mit neuen Informationen an die Fundstelle refElemInfo Eigentum beigefügt. Es ist nicht üblich, Ihre eigenen Daten auf eine einzelne HTML-Element der Benutzeroberfläche legen, aber in diesem Fall ist es unbedingt erforderlich aus Gründen, die mit einem Benutzer schwebt die Maus über das Element zu tun.

Wenn der Benutzer die Maus über einen Ticker, möchten Sie dem Ticker-Informationen in den schwimmenden iframe-Fenster geladen werden. Dies wird durch die DynamicIterator.HightlightItem Methode, die wie folgt definiert ist vollbracht.

 Quelle: / client / scripts / Jaxson / uimorphing.js (DynamicIterator)highlightItem: function (elem) (if (this.lastElem! = null) (this.shrinkElement (this.lastElem);) this.expandElement (elem); this.lastElem = elem; this.fetch (elem.refElemInfo);) ,

highlightItem nichts weiter als Delegierter die Aktionen mit den shrinkElement, expandElement und Methoden zu holen. Alle diese Methoden sind standardmäßig leer Funktionen, die die HTML-Seite benötigt zur Umsetzung. Die Idee ist es, eine highlightItem clickless Navigation einzubeziehen. Wie Sie die Navigation-Funktion liegt in der Verantwortung der HTML-Seite. DynamicIterator Verantwortung ist die Koordination. So ist der erste Schritt, um wieder normal das letzte Element, dass hervorgehoben wurde, war mit dem shrinkElement Methode zu ändern. Im Fall von dem Ticker-Beispiel, es ist wie folgt implementiert.

 Quelle: / client / ajaxrest Artikel / Architektur / dynamiclist.html DynamicIterator.shrinkElement = function (elem) (elem.style.fontSize = 12;)

Die Ticker-Umsetzung ist, dass es schrumpft die Schriftart der Tabellenzelle auf 12 einfach. Für amore ausgereifte Benutzeroberfläche, schrumpft das Element hätte gedacht Schließen Sie ein Menü oder ein Pop-up-div-Element. Der nächste Schritt besteht darin aufzuzeigen, highlightItem das aktuelle Element mit dem expandElement-Funktion, die wie folgt umgesetzt wird.

 Quelle: / client / ajaxrest Artikel / Architektur / dynamiclist.html DynamicIterator.expandElement = function (elem) (elem.style.fontSize = 30; var asynchronen = FactoryHttp.getCachedAsynchronous (); asynchronous.settings = (onComplete: function (xmlhttp) () ) asynchronous.get (elem.refElemInfo.url);)

Die expandElement Umsetzung macht zwei Dinge: erhöht die Größe der Schrift und lädt die Daten mit den Metadaten-Element zugeordnet ist. Doch bei der Umsetzung der onComplete, es gibt kein Handeln, denn wenn man die Metadaten-Element zu markieren, sind Sie wahrscheinlich nicht daran interessiert, die Anzeige der Daten, aber Sie sind in die Zwischenspeicherung der Daten für die Zukunft schnell Interessenten. An dieser Stelle müssen Sie eine Entscheidung über den Mechanismus der Darstellung der Daten, die im iframe zu machen. Wenn Sie die Daten mit einem Klick anzeigen lassen wollen, dann müssen Sie onclick für die einzelnen Zellen in einer Tabelle umzusetzen. Wenn Sie auf den Akt der Hervorhebung als Auslöser, um die Daten anzuzeigen, müssen Sie die onComplete Methode, die ich gerade gesagt habe nicht umgesetzt werden müssen umsetzen zu verwenden. Mein Punkt ist, dass die Art und Weise zeigen Sie die Daten bis zu Ihnen ist und DynamicIterator definiert keinen Rahmen. DynamicIterator ist nur für die Vorspannung der Daten. Einige Leser mögen denken, dass das Abrufen von Daten jeder Zeit ein Metadaten-Element markiert ist, ist sehr teuer, aber die Kosten hängt davon ab, wie Sie Ihren Cache implementiert. Dies bedeutet, dass, wenn Asynchronous verwiesen wird, das erste, was es tut, ist zu überprüfen den Cache für die Informationen. Wenn die Informationen nicht bereits vorliegen, ist die onComplete Methode direkt aufgerufen werden. Der Trick liegt im Cache, und wenn es kein Cache, dann jedes Mal die Metadaten-Element markiert ist, die Daten mit der Ressource zugeordnet werden geladen.

Let's Schritt zurück und denken über die Durchführung des Client-Architektur und wie sie löst unser Problem der großen Datenmengen oder langsam. Wenn wir die Arbeit mit einem E-Mail-Anwendung, dann wäre die Metadaten der einzelnen E-Mail-Titel, und wir würden über die Titel zu durchlaufen und markieren Sie sie. Um für neue E-Mails zu überprüfen, können wir ein Spin-off-Thread, der Metadaten-Elemente automatisch an das Ende der arrElements Array würde. Als wir über die E-Mail Titel durchlaufen, würden ihre Inhalte heruntergeladen und in der iframe-Fenster angezeigt. Lassen Sie uns jetzt sagen, dass wir die Berechnung wurden alle Primzahlen und wollten die Ergebnisse zu sehen. In diesem Fall wird die Metadaten der Daten, und wie die E-Mail-Anwendung, so würde ein Thread abgespalten zu halten indem Ergebnisse an die arrElements Array. Erwähnte ich diese beiden Beispiele von Fäden gesponnen aus, da bisher das Beispiel zeigt nur die Expansion und Laden von Daten, wenn der Benutzer sie anfordert. Mit Hilfe von JavaScript Fäden, werden die Daten automatisch, ohne dass der Benutzer danach fragen geladen.

Ein Artikel eingereicht von Sonja Lande


Disclaimer:Unsere Website ist nicht verantwortlich für den Inhalt dieses Artikels. Webarticles ist eine kostenlose Informationsquelle.
Wichtig: Dieser Artikel "Multithreading in JavaScript" wurde durch ein automatisches Software übersetzt. Wir fühlen uns leid für alle Rechtschreibfehler, die möglicherweise aufgetreten sind. Vielen Dank für Ihr Verständnis.


Online: 417 users browsing the articles directory