Soweit ich das beurteilen kann, müssen Web-Worker in eine separate JavaScript-Datei geschrieben und wie folgt aufgerufen werden:
new Worker('longrunning.js')
Ich verwende den Closure-Compiler, um meinen gesamten JavaScript-Quellcode zu kombinieren und zu minimieren, und ich möchte meine Mitarbeiter lieber nicht in separaten Dateien für die Verteilung haben. Gibt es eine Möglichkeit, dies zu tun?
new Worker(function() {
//Long-running work here
});
Angesichts der Tatsache, dass erstklassige Funktionen für JavaScript so wichtig sind, warum muss die Standardmethode für Hintergrundarbeiten eine ganze andere JavaScript-Datei vom Webserver laden?
javascript
web-worker
Ben Dilts
quelle
quelle
var worker = new DynWorker(); worker.inject("foo", function(){...});
...Antworten:
http://www.html5rocks.com/de/tutorials/workers/basics/#toc-inlineworkers
Vollständiges Beispiel für einen BLOB-Inline-Worker:
quelle
Die html5rocks-Lösung zum Einbetten des Web-Worker-Codes in HTML ist ziemlich schrecklich.
Und ein Blob von maskiertem JavaScript als Zeichenfolge ist nicht besser, nicht zuletzt, weil es den Arbeitsablauf verkompliziert (der Closure-Compiler kann nicht mit Zeichenfolgen arbeiten).
Persönlich mag ich die toString-Methoden wirklich, aber @ dan-man DIESER Regex!
Mein bevorzugter Ansatz:
Unterstützung ist der Schnittpunkt dieser drei Tabellen:
Dies funktioniert jedoch nicht für einen SharedWorker , da die URL genau übereinstimmen muss, auch wenn der optionale Parameter 'name' übereinstimmt. Für einen SharedWorker benötigen Sie eine separate JavaScript-Datei.
Update 2015 - Die ServiceWorker-Singularität kommt an
Jetzt gibt es eine noch leistungsfähigere Möglichkeit, dieses Problem zu lösen. Speichern Sie den Worker-Code erneut als Funktion (anstelle einer statischen Zeichenfolge) und konvertieren Sie ihn mit .toString (). Fügen Sie dann den Code unter einer statischen URL Ihrer Wahl in CacheStorage ein.
Es gibt zwei mögliche Rückschläge. ObjectURL wie oben oder nahtloser setzen eine echte JavaScript-Datei unter /my_workers/worker1.js ablegen
Vorteile dieses Ansatzes sind:
quelle
Sie können eine einzelne JavaScript-Datei erstellen, die den Ausführungskontext kennt und sowohl als übergeordnetes Skript als auch als Worker fungieren kann. Beginnen wir mit einer Grundstruktur für eine Datei wie diese:
Wie Sie sehen können, enthält das Skript den gesamten Code sowohl aus Sicht des Elternteils als auch des Arbeitnehmers und prüft, ob es sich bei seiner eigenen Instanz um einen Arbeiter handelt
!document
. Die etwas unhandlichescript_path
Berechnung wird verwendet, um den Pfad des Skripts relativ zur übergeordneten Seite genau zu berechnen, da der angegebene Pfadnew Worker
relativ zur übergeordneten Seite und nicht zum Skript ist.quelle
Unter Verwendung des
Blob
Verfahrens, wie über dieses für einen Arbeiter Fabrik:Sie könnten es also so verwenden ...
BEARBEITEN:
Ich habe diese Idee gerade weiter ausgebaut, um die Thread -übergreifende Kommunikation zu vereinfachen: Bridged-Worker.js .
EDIT 2:
Der obige Link führt zu einem Kern, den ich erstellt habe. Jemand anderes verwandelte es später in ein echtes Repo .
quelle
Web-Worker arbeiten in völlig getrennten Kontexten als einzelne Programme.
Dies bedeutet, dass Code nicht in Objektform von einem Kontext in einen anderen verschoben werden kann, da sie dann über Schließungen, die zum anderen Kontext gehören, auf Objekte verweisen können.
Dies ist besonders wichtig, da ECMAScript als einzelne Thread-Sprache konzipiert ist. Da Web-Worker in separaten Threads arbeiten, besteht das Risiko, dass nicht thread-sichere Vorgänge ausgeführt werden.
Dies bedeutet wiederum, dass Web-Worker mit Code in Quellform initialisiert werden müssen.
Die Spezifikation von WHATWG sagt
aber leider erklärt es nicht wirklich, warum man nicht zulassen konnte, dass eine Zeichenfolge mit Quellcode an den Konstruktor übergeben wurde.
quelle
Ein besser lesbarer Weg für einen Inline-Mitarbeiter.
quelle
toString()
, den Körper extrackiert und diese dann in einen Blob eingefügt habe. Überprüfen Sie bei der letzten Antwort, ich habe ein BeispielNehmen Sie Adrias Antwort und fügen Sie sie in eine kopierbare Funktion ein, die mit aktuellem Chrome und FF, jedoch nicht mit IE10 funktioniert (Worker from Blob verursacht einen Sicherheitsfehler ).
Und hier ist ein funktionierendes Beispiel: http://jsfiddle.net/ubershmekel/YYzvr/
quelle
Letzte Antwort (2018)
Sie können Greenlet verwenden :
Beispiel:
quelle
Abhängig von Ihrem Anwendungsfall können Sie so etwas wie verwenden
Ein Beispiel wäre
quelle
Schauen Sie sich das vkThread-Plugin an. Mit diesem Plugin können Sie jede Funktion in Ihrem Hauptcode übernehmen und in einem Thread (Web Worker) ausführen. Sie müssen also keine spezielle "Web-Worker-Datei" erstellen.
http://www.eslinstructor.net/vkthread/
- Vadim
quelle
Sie können Web-Worker in demselben Javascript verwenden, indem Sie Inline-Webworker verwenden.
Der folgende Artikel befasst sich mit dem Verständnis der Webworker und ihrer Einschränkungen sowie dem Debuggen von Webworkern.
Mastering in Webworkern
quelle
Ich denke, der bessere Weg, dies zu tun, ist die Verwendung eines Blob-Objekts. Unten sehen Sie ein einfaches Beispiel.
quelle
Versuchen Sie, jThread zu verwenden. https://github.com/cheprasov/jThread
quelle
hier Konsole:
quelle
https://developer.mozilla.org/es/docs/Web/Guide/Performance/Using_web_workers
quelle
Verwenden Sie mein kleines Plugin https://github.com/zevero/worker-create
quelle
Ich denke, wir haben jetzt dank der Vorlagenliterale in ES6 eine weitere coole Option dafür. Auf diese Weise können wir auf die zusätzliche Worker-Funktion (und ihren seltsamen Umfang) verzichten und einfach den Code, der für den Worker bestimmt ist, als mehrzeiligen Text schreiben, ähnlich wie in dem Fall, in dem wir Text gespeichert haben, ohne jedoch ein Dokument oder ein DOM zu benötigen um das in zu tun. Beispiel:
Hier ist ein Kern des Restes dieses Ansatzes .
Beachten Sie, dass wir alle zusätzlichen Funktionsabhängigkeiten, die wir möchten, in den Worker ziehen können, indem wir sie in einem Array sammeln und .toString auf jedem von ihnen ausführen, um sie ebenfalls in Zeichenfolgen zu reduzieren (sollte funktionieren, solange es sich um Funktionsdeklarationen handelt) und Stellen Sie das dann einfach der Skriptzeichenfolge voran. Auf diese Weise müssen wir keine Skripte importieren, die wir möglicherweise bereits in den Bereich des Codes gebündelt haben, den wir schreiben.
Der einzige wirkliche Nachteil dieser speziellen Version ist, dass Linters den Service-Worker-Code nicht fusseln können (da es sich nur um eine Zeichenfolge handelt), was ein Vorteil für den "separaten Worker-Funktionsansatz" ist.
quelle
Dies ist nur eine Ergänzung zu den oben genannten - ich habe eine schöne Vorlage zum Testen von Web-Workern in jsFiddle. Anstelle von Blob wird jsFiddles
?js
api verwendet:Normale Web Worker- und Shared Worker- Vorlagen sind verfügbar.
quelle
Ich habe festgestellt, dass CodePen derzeit keine Inline-
<script>
Tags mit Syntaxhervorhebung hervorhebt , die es nicht sindtype="text/javascript"
(oder die kein Typattribut haben).Daher habe ich eine ähnliche, aber etwas andere Lösung mit beschrifteten Blöcken mit
break
entwickelt. Dies ist die einzige Möglichkeit, ein<script>
Tag zu verlassen, ohne eine Wrapper-Funktion zu erstellen (was nicht erforderlich ist).quelle
Eine einfache versprochene Version,
Function#callAsWorker
die ein thisArg und Argumente (genau wiecall
) verwendet und ein Versprechen zurückgibt:quelle
close()
Methode hinzufügen , um Ihren Web-Worker-Life-Hook zu schließen. developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/…close
Funktion ist veraltet. Arbeitnehmer können jedoch gekündigt werden . Ich habe das jetzt hinzugefügt.Ich verwende Code wie diesen. Sie können Ihre Onmessage als eine andere Funktion als Nur-Text definieren, damit der Editor Ihren Code hervorheben kann und jshint funktioniert.
quelle
Ja, es ist möglich, ich habe es mit Blob-Dateien gemacht und einen Rückruf weitergeleitet
Ich werde Ihnen zeigen, was eine Klasse, die ich geschrieben habe, tut und wie sie die Ausführung von Rückrufen im Hintergrund verwaltet.
Zuerst instanziieren Sie das
GenericWebWorker
mit den Daten, die Sie an den Rückruf übergebenWeb Worker
möchten, der in ausgeführt wird. Dazu gehören Funktionen, die Sie verwenden möchten, in diesem Fall eine Nummer, ein Datum und eine aufgerufene Funktionblocker
Diese Blockerfunktion führt für n Millisekunden eine unendliche Zeit aus
und dann benutzt du es so
quelle
Sie können den Inhalt Ihrer Datei worker.js in Backticks platzieren (was eine mehrzeilige Zeichenfolgenkonstante ermöglicht) und den Worker aus einem Blob wie folgt erstellen:
Dies ist praktisch, wenn Sie aus irgendeinem Grund keine separaten Skript-Tags für den Worker haben möchten.
quelle
Eine andere Lösung besteht darin, den Worker in eine Funktion zu verpacken und dann einen Blob zu erstellen, der die Funktion wie folgt aufruft:
quelle
Einzeiler für die Ausführung von Funktionen bei Arbeitnehmern:
Anwendungsbeispiel:
quelle