Pour autant que je sache, les travailleurs Web doivent être écrits dans un fichier JavaScript séparé et appelés comme ceci:
new Worker('longrunning.js')
J'utilise le compilateur de fermeture pour combiner et réduire tout mon code source JavaScript, et je préfère ne pas avoir mes employés dans des fichiers séparés pour la distribution. Y a-t-il un moyen de le faire?
new Worker(function() {
//Long-running work here
});
Étant donné que les fonctions de première classe sont si cruciales pour JavaScript, pourquoi la méthode standard de travail en arrière-plan doit-elle charger un autre fichier JavaScript à partir du serveur Web?
javascript
web-worker
Ben Dilts
la source
la source
var worker = new DynWorker(); worker.inject("foo", function(){...});
...Réponses:
http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers
Exemple complet de travailleur en ligne BLOB:
la source
La solution html5rocks consistant à incorporer le code du travailleur Web en HTML est assez horrible.
Et un blob de JavaScript échappé en tant que chaîne n'est pas mieux, notamment parce qu'il complique le flux de travail (le compilateur de fermeture ne peut pas fonctionner sur les chaînes).
Personnellement, j'aime vraiment les méthodes toString, mais @ dan-man QUE regex!
Mon approche préférée:
Le support est l'intersection de ces trois tables:
Cependant, cela ne fonctionnera pas pour un SharedWorker , car l'URL doit être une correspondance exacte, même si le paramètre facultatif «nom» correspond. Pour un SharedWorker, vous aurez besoin d'un fichier JavaScript distinct.
Mise à jour 2015 - La singularité ServiceWorker arrive
Il existe maintenant un moyen encore plus puissant de résoudre ce problème. Encore une fois, stockez le code de travail en tant que fonction (plutôt qu'une chaîne statique) et convertissez-le à l'aide de .toString (), puis insérez le code dans CacheStorage sous une URL statique de votre choix.
Il existe deux solutions de rechange possibles. ObjectURL comme ci-dessus, ou de manière plus transparente, placez un vrai fichier JavaScript dans /my_workers/worker1.js
Les avantages de cette approche sont:
la source
Vous pouvez créer un fichier JavaScript unique qui connaît son contexte d'exécution et peut agir à la fois comme script parent et comme travailleur. Commençons par une structure de base pour un fichier comme celui-ci:
Comme vous pouvez le voir, le script contient tout le code du point de vue du parent et du travailleur, vérifiant si sa propre instance individuelle est un travailleur avec
!document
. Lescript_path
calcul quelque peu compliqué est utilisé pour calculer avec précision le chemin d'accès du script par rapport à la page parent, car le chemin d'accès fourninew Worker
est relatif à la page parent, pas au script.la source
En utilisant la
Blob
méthode, que diriez-vous de cela pour une usine de travailleurs:Vous pouvez donc l'utiliser comme ça ...
ÉDITER:
Je viens d'étendre cette idée pour faciliter la communication inter-threads: bridged-worker.js .
EDIT 2:
Le lien ci-dessus est vers un résumé que j'ai créé. Quelqu'un d'autre l'a transformé plus tard en un véritable repo .
la source
Les travailleurs du Web opèrent dans des contextes entièrement distincts en tant que programmes individuels.
Cela signifie que le code ne peut pas être déplacé d'un contexte à un autre sous forme d'objet, car ils pourraient alors référencer des objets via des fermetures appartenant à l'autre contexte.
Ceci est particulièrement important car ECMAScript est conçu pour être un langage à thread unique, et comme les travailleurs Web opèrent dans des threads séparés, vous risquez alors d'effectuer des opérations non sécurisées pour les threads.
Cela signifie à nouveau que les travailleurs Web doivent être initialisés avec du code sous forme source.
La spécification de WHATWG dit
mais malheureusement, cela n'explique pas vraiment pourquoi on ne pouvait pas permettre de passer une chaîne avec du code source au constructeur.
la source
une meilleure façon de lire pour un travailleur en ligne ..
la source
toString()
, extraire le corps et ensuite le mettre dans un Blob. Vérifiez à la dernière réponse, j'ai un exemplePrendre la réponse d'Adria et la mettre dans une fonction copier-coller qui fonctionne avec Chrome et FF actuels mais pas IE10 (le travailleur de blob provoque une erreur de sécurité ).
Et voici un exemple de travail http://jsfiddle.net/ubershmekel/YYzvr/
la source
Réponse récente (2018)
Vous pouvez utiliser Greenlet :
Exemple:
la source
Selon votre cas d'utilisation, vous pouvez utiliser quelque chose comme
Un exemple serait
la source
Jetez un œil au plugin vkThread. Avec le plugin htis, vous pouvez prendre n'importe quelle fonction dans votre code principal et l'exécuter dans un thread (Web Worker). Ainsi, vous n'avez pas besoin de créer un "fichier de travail Web" spécial.
http://www.eslinstructor.net/vkthread/
--Vadim
la source
Vous pouvez utiliser des travailleurs Web dans la même firme javascript en utilisant des travailleurs Web en ligne.
L'article ci-dessous vous aidera à comprendre facilement les travailleurs Web et leurs limites et le débogage des travailleurs Web.
Maîtrise des webworkers
la source
Je pense que la meilleure façon de le faire est d'utiliser un objet Blob, ci-dessous vous pouvez voir un exemple simple.
la source
Essayez d'utiliser jThread. https://github.com/cheprasov/jThread
la source
ici console:
la source
https://developer.mozilla.org/es/docs/Web/Guide/Performance/Using_web_workers
la source
Utilisez mon petit plugin https://github.com/zevero/worker-create
la source
Je pense donc que nous avons une autre option intéressante pour cela maintenant, grâce aux modèles de littéraux dans ES6. Cela nous permet de nous passer de la fonction de travail supplémentaire (et de sa portée étrange) et d'écrire simplement le code qui est destiné au travailleur en tant que texte multiligne, un peu comme dans le cas où nous utilisions pour stocker du texte, mais sans avoir réellement besoin d'un document ou d'un DOM pour le faire. Exemple:
Voici un aperçu du reste de cette approche .
Notez que nous pouvons insérer toutes les dépendances de fonction supplémentaires que nous voulons dans le travailleur simplement en les collectant dans un tableau et en exécutant .toString sur chacune d'entre elles pour les réduire également en chaînes (cela devrait fonctionner tant qu'elles sont des déclarations de fonction) et puis en ajoutant simplement cela à la chaîne de script. De cette façon, nous n'avons pas à importer des scripts que nous pourrions déjà avoir inclus dans la portée du code que nous écrivons.
Le seul véritable inconvénient de cette version particulière est que les linters ne seront pas en mesure de linter le code du service worker (car il ne s'agit que d'une chaîne), ce qui est un avantage pour "l'approche de fonction de travail séparée".
la source
Ce n'est qu'un ajout à ce qui précède - j'ai de beaux modèles pour tester les travailleurs Web dans jsFiddle. Plutôt que Blob, il utilise l'API jsFiddles
?js
:Des modèles de travailleur Web normal et de travailleur partagé sont disponibles.
la source
J'ai découvert que CodePen actuellement ne met pas en évidence la syntaxe des
<script>
balises en ligne qui ne le sont pastype="text/javascript"
(ou qui n'ont pas d'attribut de type).J'ai donc imaginé une solution similaire mais légèrement différente en utilisant des blocs étiquetés avec
break
, qui est le seul moyen de libérer une<script>
balise sans créer de fonction wrapper (ce qui n'est pas nécessaire).la source
Une version simple promis
Function#callAsWorker
, qui prend un thisArg et des arguments (commecall
), et retourne une promesse:la source
close()
méthode pour fermer votre hook de vie de travailleur Web. developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/…close
fonction est déconseillée. Cependant, les travailleurs peuvent être licenciés . Je l'ai ajouté maintenant.J'utilise du code comme celui-ci, vous pouvez définir votre onmessage comme une fonction autre que du texte brut, afin que l'éditeur puisse mettre en évidence votre code et vos travaux jshint.
la source
Oui, c'est possible, je l'ai fait en utilisant des fichiers Blob et en passant un rappel
Je vais vous montrer ce que fait une classe que j'ai écrite et comment elle gère l'exécution des rappels en arrière-plan.
D'abord, vous instanciez le
GenericWebWorker
avec toutes les données que vous souhaitez transmettre au rappel qui sera exécuté dans leWeb Worker
, qui comprend les fonctions que vous souhaitez utiliser, dans ce cas un nombre, une date et une fonction appeléeblocker
Cette fonction de blocage exécutera un infini pendant n millisecondes
puis vous l'utilisez comme ça
la source
Vous pouvez placer le contenu de votre fichier worker.js à l'intérieur de backticks (ce qui permet une constante de chaîne multiligne) et créer le travailleur à partir d'un blob comme ceci:
C'est pratique si, pour une raison quelconque, vous ne voulez pas avoir de balises de script distinctes pour le travailleur.
la source
Une autre solution consiste simplement à envelopper le Worker dans une fonction, puis à créer un blob appelant la fonction comme suit:
la source
One-liner pour exécuter des fonctions chez les travailleurs:
Exemple d'utilisation:
la source