1. Comment exécuter plusieurs travailleurs Web? J'ai essayé une boucle forcée ressemblant à ceci:
Il n'y a aucun problème avec la création de plus d'un travailleur, même si vous ne gardez pas trace d'eux dans un tableau. Voir ci-dessous.
2. Comment contrôlerais-je que tous ont fini leur travail? (Je dois réassemblage le tableau et travailler avec elle plus tard)
Ils peuvent poster un message à vous quand ils sont faits, avec les résultats. Exemple ci-dessous
3. Combien de travailleurs Web apportent-ils vraiment une amélioration?
Quelle est la longueur d'un morceau de ficelle? :-) La réponse dépendra entièrement de la machine cible sur laquelle elle est en cours d'exécution. Beaucoup de gens ont aujourd'hui quatre noyaux ou plus sur leurs machines. Bien sûr, la machine fait beaucoup d'autres choses aussi. Vous devrez syntoniser votre environnement cible.
4. Existe-t-il un didacticiel avancé, en plus de l'entrée MDN?
Il n'y a pas beaucoup de "avancé" sur les web workers. :-) J'ai trouvé this article était suffisant.
Voici un exemple cinq travailleurs en cours d'exécution et de regarder pour eux à faire:
fenêtre principale:
(function() {
var n, worker, running;
display("Starting workers...");
running = 0;
for (n = 0; n < 5; ++n) {
workers = new Worker("worker.js");
workers.onmessage = workerDone;
workers.postMessage({id: n, count: 10000});
++running;
}
function workerDone(e) {
--running;
display("Worker " + e.data.id + " is done, result: " + e.data.sum);
if (running === 0) { // <== There is no race condition here, see below
display("All workers complete");
}
}
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
})();
worker.js
:
this.onmessage = function(e) {
var sum, n;
sum = 0;
for (n = 0; n < e.data.count; ++n) {
sum += n;
}
this.postMessage({id: e.data.id, sum: sum});
};
A propos de la condition de la race qui n'existe pas : Si vous pensez en termes de threading préemptive vrai, alors vous pourriez penser: Je pourrais créer un travailleur, incrémenter running
à 1
, puis avant de créer le prochain travailleur, je pourrais obtenir le message de la première qu'il a fait, décrémenter running
à 0
, et pense à tort que tous les travailleurs ont été faits. Cela ne peut pas se produire dans l'environnement des travailleurs Web. Bien que l'environnement soit bienvenu pour démarrer le travailleur dès qu'il le souhaite, et un travailleur pourrait bien finir avant que le code de démarrage des travailleurs ne finisse, tout ce qu'il ferait file d'attente un appel à la fonction workerDone
pour le thread JavaScript principal. Il n'y a pas de préemption. Et donc nous savons que tous les travailleurs ont été démarrés avant le premier appel à workerDone
est effectivement exécuté. Ainsi, quand running
est 0
, nous savons qu'ils sont tous finis.
Note finale: Dans ce qui précède, j'utilise onmessage = ...
pour raccorder des gestionnaires d'événements. Naturellement, cela signifie que je ne peux avoir qu'un gestionnaire d'événements sur l'objet avec lequel je fais cela. Si vous devez disposer de plusieurs gestionnaires pour l'événement message
, utilisez addEventListener
. Tous les navigateurs qui prennent en charge les travailleurs Web prennent en charge addEventListener
sur eux (vous ne devez pas vous inquiéter de la chose IE attachEvent
).
Pour # 2: Il faudrait utiliser 'postMessage' du travailleur de renvoyer une message à ce parent JS disant que le travailleur a terminé le traitement (et probablement passer les résultats) ...vous devrez donc ajouter un écouteur 'onmessage' pour chaque travailleur, dans la boucle. Vous stockez toutes ces réponses dans un tableau. Lorsque le nombre de réponses dans le tableau est le même que le nombre de travailleurs créés, cela signifie que tout est fait ... et vous pouvez gérer ce tableau que vous avez créé. Cela peut être rendu plus «propre» en utilisant le concept des objets différés de jQuery. – Ian
«Ne peut pas être cloné» signifie que ce que vous transmettez à l'ouvrier n'a pas pu être cloné. Pour éviter les conditions de concurrence, les objets ne sont jamais partagés entre les travailleurs et le thread principal. Les objets doivent soit être copiés dans l'espace mémoire du worker, soit (avec des Blob et des tableaux typés) le thread principal peut abandonner de l'espace mémoire à un worker et perdre la référence à l'objet. – apsillers
Ok. Lisez à ce sujet, mais l'ai oublié. En tous cas. Si je crée une variable temporaire dans la boucle, sécuriser le tableau en tant que chaîne et transmettre cette chaîne, serait-ce une meilleure solution? Quelque part j'ai lu, que j'envoie seulement des cordes aux ouvriers, ailleurs dit-il, que je peux transférer des variables? Merci à vous deux pour votre explication, aidez-moi à commencer! –