O ile mi wiadomo, pracownicy sieci muszą być zapisani w osobnym pliku JavaScript i nazywani w ten sposób:
new Worker('longrunning.js')
Używam kompilatora zamykającego do łączenia i minimalizowania całego kodu źródłowego JavaScript i wolałbym nie mieć swoich pracowników w osobnych plikach do dystrybucji. Czy jest jakiś sposób, aby to zrobić?
new Worker(function() {
//Long-running work here
});
Biorąc pod uwagę, że pierwszorzędne funkcje są tak ważne dla JavaScript, dlaczego standardowy sposób wykonywania pracy w tle musi ładować cały inny plik JavaScript z serwera WWW?
javascript
web-worker
Ben Dilts
źródło
źródło
var worker = new DynWorker(); worker.inject("foo", function(){...});
...Odpowiedzi:
http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers
Pełny przykład wbudowanego pracownika BLOB:
źródło
Rozwiązanie HTML5rocks polegające na osadzaniu kodu roboczego w HTML jest dość okropne.
A kropla uciekającego kodu JavaScript jako ciąg znaków nie jest lepsza, zwłaszcza dlatego, że komplikuje przepływ pracy (kompilator Closure nie może działać na ciągach znaków).
Osobiście bardzo lubię metody toString, ale @ dan-man TO wyrażenie regularne!
Moje preferowane podejście:
Wsparcie to przecięcie tych trzech tabel:
Nie będzie to jednak działać dla SharedWorker , ponieważ adres URL musi być dokładnie zgodny, nawet jeśli opcjonalny parametr „name” pasuje. Dla SharedWorker potrzebujesz osobnego pliku JavaScript.
Aktualizacja 2015 - Nadchodzi osobliwość ServiceWorker
Teraz istnieje jeszcze skuteczniejszy sposób rozwiązania tego problemu. Ponownie przechowuj kod roboczy jako funkcję (zamiast ciągu statycznego) i konwertuj za pomocą .toString (), a następnie wstaw kod do CacheStorage pod wybranym statycznym adresem URL.
Możliwe są dwa awarie. ObjectURL jak wyżej lub bardziej płynnie, umieść prawdziwy plik JavaScript na /my_workers/worker1.js
Zalety tego podejścia to:
źródło
Możesz utworzyć pojedynczy plik JavaScript, który jest świadomy jego kontekstu wykonywania i może działać zarówno jako skrypt nadrzędny, jak i proces roboczy. Zacznijmy od podstawowej struktury pliku takiego jak ten:
Jak widać, skrypt zawiera cały kod zarówno z punktu widzenia rodzica, jak i pracownika, sprawdzając, czy jego własna indywidualna instancja jest robotnikiem
!document
. Nieco nieporęcznescript_path
obliczenia służą do dokładnego obliczenia ścieżki skryptu względem strony nadrzędnej, ponieważ podana ścieżkanew Worker
jest względem strony nadrzędnej, a nie skryptu.źródło
Korzystając z
Blob
metody, co powiesz na to dla fabryki pracowników:Możesz więc użyć go w ten sposób ...
EDYTOWAĆ:
Właśnie rozszerzyłem ten pomysł, aby ułatwić komunikację między wątkami: bridged-worker.js .
EDYCJA 2:
Powyższy link prowadzi do utworzonej przeze mnie treści. Ktoś później przekształcił go w rzeczywiste repo .
źródło
Pracownicy sieci pracują w całkowicie odrębnych kontekstach jako poszczególne programy.
Oznacza to, że kodu nie można przenosić z jednego kontekstu do drugiego w formie obiektowej, ponieważ mogłyby one wówczas odwoływać się do obiektów poprzez zamknięcia należące do innego kontekstu.
Jest to szczególnie ważne, ponieważ ECMAScript został zaprojektowany jako język jednowątkowy, a ponieważ pracownicy sieci pracują w osobnych wątkach, istnieje ryzyko, że zostaną wykonane operacje nieobsługujące wątków.
To znowu oznacza, że pracownicy sieci muszą zostać zainicjowani kodem w postaci źródłowej.
Specyfikacja WHATWG mówi
ale niestety tak naprawdę nie wyjaśnia, dlaczego nie można było pozwolić konstruktorowi przekazać łańcucha z kodem źródłowym.
źródło
lepszy sposób na przeczytanie dla pracownika wbudowanego ..
źródło
toString()
roboczym , przekazałem tę funkcję , wyrzuciłem treść, a następnie umieściłem ją w obiekcie Blob. Sprawdź ostatnią odpowiedź, mam przykładPrzyjmowanie odpowiedzi Adrii i włączenie jej do funkcji kopiowalnej, która działa z obecnymi Chrome i FF, ale nie IE10 (pracownik z obiektu blob powoduje błąd bezpieczeństwa ).
A oto działający przykład http://jsfiddle.net/ubershmekel/YYzvr/
źródło
Ostatnia odpowiedź (2018)
Możesz użyć Greenleta :
Przykład:
źródło
W zależności od przypadku użycia możesz użyć czegoś takiego
Przykładem może być
źródło
Spójrz na wtyczkę vkThread. Dzięki wtyczce htis możesz przejąć dowolną funkcję w głównym kodzie i wykonać ją w wątku (pracownik sieciowy). Nie musisz więc tworzyć specjalnego „pliku roboczego”.
http://www.eslinstructor.net/vkthread/
- Vadim
źródło
Możesz używać pracowników sieci Web w tym samym pliku JavaScript, używając wbudowanych pracowników sieci.
Poniższy artykuł skieruje Cię do łatwego zrozumienia webworkerów i ich ograniczeń oraz debugowania webmasterów.
Opanowanie w webmasterach
źródło
Myślę, że lepszym sposobem na to jest użycie obiektu Blob, poniżej możesz zobaczyć prosty przykład.
źródło
Spróbuj użyć jThread. https://github.com/cheprasov/jThread
źródło
tutaj konsola:
źródło
https://developer.mozilla.org/es/docs/Web/Guide/Performance/Using_web_workers
źródło
Użyj mojej małej wtyczki https://github.com/zevero/worker-create
źródło
Myślę więc, że mamy teraz kolejną fajną opcję, dzięki literałom szablonów w ES6. To pozwala nam zrezygnować z dodatkowej funkcji pracownika (i jej dziwnego zakresu) i po prostu napisać kod przeznaczony dla pracownika jako tekst wielowierszowy, podobnie jak w przypadku, gdy używaliśmy do przechowywania tekstu, ale bez potrzeby posiadania dokumentu lub DOM zrobić to w. Przykład:
Oto sedno tego podejścia .
Zauważ, że możemy pobrać dowolne dodatkowe zależności funkcji, które chcemy, do robota, po prostu zbierając je do tablicy i uruchamiając .toString na każdym z nich, aby zredukować je również do ciągów (powinny działać, dopóki są deklaracjami funkcji) i a następnie po prostu dodając go do ciągu skryptu. W ten sposób nie musimy importować skryptów, które mogliśmy już włączyć do zakresu pisanego przez nas kodu.
Jedynym prawdziwym minusem tej konkretnej wersji jest to, że linters nie będą w stanie pobrudzić kodu pracownika usługi (ponieważ jest to tylko ciąg znaków), co jest zaletą dla „osobnego podejścia do funkcji pracownika”.
źródło
To tylko dodatek do powyższego - mam ładne szablony do testowania robotów WWW w jsFiddle. Zamiast Blob używa jsFiddles
?js
api:Dostępne są normalne szablony procesów roboczych i udostępnione szablony procesów roboczych .
źródło
Odkryłem, że CodePen obecnie nie wyróżnia
<script>
znaczników wbudowanych , które nie sątype="text/javascript"
(lub które nie mają atrybutu type).Wymyśliłem więc podobne, ale nieco inne rozwiązanie, używając bloków z etykietami
break
, co jest jedynym sposobem na zwolnienie z<script>
tagu bez tworzenia funkcji otoki (co jest niepotrzebne).źródło
Prosta wersja obiecana
Function#callAsWorker
, która przyjmuje thisArg i argumenty (podobnie jakcall
) i zwraca obietnicę:źródło
close()
metodę, aby zamknąć hak na życie pracownika sieci. developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/…close
funkcja jest przestarzała. Jednak pracownicy mogą zostać rozwiązani . Dodałem to teraz.Używam takiego kodu, możesz zdefiniować swój komunikat jako funkcję inną niż zwykły tekst, dzięki czemu edytor może podświetlić kod i działa jshint.
źródło
Tak, jest to możliwe, zrobiłem to przy użyciu plików Blob i przekazując oddzwonienie
Pokażę ci, co pisze klasa i jak zarządza wykonywaniem wywołań zwrotnych w tle.
Najpierw utwórz instancję
GenericWebWorker
z dowolnymi danymi, które chcesz przekazać do wywołania zwrotnego, które będą wykonywane wWeb Worker
, który obejmuje funkcje, których chcesz użyć, w tym przypadku liczbę, datę i funkcję o nazwieblocker
Ta funkcja blokująca będzie wykonywać nieskończoność przez n milisekund
a następnie używasz go w ten sposób
źródło
Możesz umieścić zawartość pliku worker.js w backticks (co pozwala na stałą ciągu wielowierszowego) i utworzyć pracownika z obiektu blob w następujący sposób:
Jest to przydatne, jeśli z jakiegokolwiek powodu nie chcesz mieć oddzielnych znaczników skryptu dla pracownika.
źródło
Innym rozwiązaniem jest po prostu owinięcie Workera w funkcję, a następnie utworzenie obiektu blob wywołującego funkcję w następujący sposób:
źródło
Jednowierszowy do uruchamiania funkcji w pracownikach:
Przykładowe użycie:
źródło