2011-09-21 17 views
14

WebWorker wykonuje z zakresem całkowicie oddzielonym od kontekstu "okna" tradycyjnego JavaScript. Czy istnieje standardowy sposób, w jaki skrypt określa, czy jest on wykonywany jako WebWorker?Dowolny standardowy mechanizm do wykrywania, czy JavaScript działa jako WebWorker?

Pierwszym "hack", o jakim myślę, byłoby wykrycie, czy w zakresie pracownika istnieje "okno". Jeśli jest nieobecny, może to oznaczać, że wykonujemy pracę jako WebWorker.

Dodatkowymi opcjami byłyby wykrywanie właściwości nieobecnych w standardowym kontekście "okna". Chrome 14, lista ta obejmuje obecnie:

FileReaderSync 
FileException 
WorkerLocation 
importScripts 
openDatabaseSync 
webkitRequestFileSystemSync 
webkitResolveLocalFileSystemSyncURL 

Wykrywanie WorkerLocation wydaje się realne kandydata, ale to nadal czuje się nieco hackish. Czy istnieje lepszy sposób?

EDYTOWANIE: Here jest JSFiddle użyłem do określenia właściwości obecnych w uruchomieniu WebWorker, które są teraz w "oknie".

+4

Dlaczego nie możesz po prostu sprawdzić "okna"? –

+0

Co powiesz na '! (Okno type ==" object "&& typeof document ==" object "&& window.document === document)'? –

Odpowiedz

12

spec mówi:

DOM API (obiekty węzła obiekty dokumentu, etc.) nie są dostępne dla pracowników w tej wersji tej specyfikacji.

Sugeruje to sprawdzenie pod kątem nieobecności document jest dobrym sposobem sprawdzenia, czy jesteś pracownikiem. Alternatywnie możesz spróbować sprawdzić obecność WorkerGlobalScope?

0

działa to dla mnie:

if (self instanceof Window) { 
    // not in worker 
} 
+0

Ale to rzuca w robotnika, gdzie zarówno 'self' i' Window' są niezdefiniowane? – Bergi

+1

nie, w robotniku, self jest instancją WorkerGlobalScope – mbelow

+1

Och, masz rację, ale 'Window' jest nadal' niezdefiniowany' i 'instanceof' rzuci się z tego powodu. – Bergi

2

Chociaż po nieco stary, dodając kilka alternatyw generycznych co jest wykorzystywane w Asynchronous.js Library (biblioteka dla rodzajowego obsługi asynchronicznego/równoległych procesów, autora) jest co następuje:

// other declarations here 
,isNode = ("undefined" !== typeof global) && ('[object global]' === Object.prototype.toString.call(global)) 
// http://nodejs.org/docs/latest/api/all.html#all_cluster 
,isNodeProcess = isNode && !!process.env.NODE_UNIQUE_ID 
,isWebWorker = !isNode && ('undefined' !== typeof WorkerGlobalScope) && ("function" === typeof importScripts) && (navigator instanceof WorkerNavigator) 
,isBrowser = !isNode && !isWebWorker && ("undefined" !== typeof navigator) && ("undefined" !== typeof document) 
,isBrowserWindow = isBrowser && !!window.opener 
,isAMD = "function" === typeof(define) && define.amd 
,supportsMultiThread = isNode || "function" === typeof Worker 
,isThread = isNodeProcess || isWebWorker 
// rest declarations here.. 
0

jest nawet więcej: WorkerNavigator itp

ile istnieje słowo kluczowe do wykrywania webworkerów, musisz użyć zmiennej. (. Nic nie może zatrzymać fałszywe skrypt uruchomiony przed skryptu od ustawiania lub zastąpienie zmiennych)

Więc zakładając, że nie ma żadnych nieuczciwych skrypty uruchomione przed swoim skrypcie, każda z tych linii będzie działać:

this.DedicatedWorkerGlobalScope?this.__proto__ === this.DedicatedWorkerGlobalScope.prototype:false 

this.WorkerGlobalScope?this.__proto__.__proto__ === this.WorkerGlobalScope.prototype:false // works for shared workers too 

this.constructor === this.DedicatedWorkerGlobalScope //or SharedWorkerGlobalScope 

!(this.DedicatedWorkerGlobalScope === undefined) 

!(this.DedicatedWorkerGlobalScope === undefined) 

Można również użyć self§ zamiast this, ale ponieważ this nie można ustawić, jest to lepsze.


wolę:

this.DedicatedWorkerGlobalScope !== undefined 

Oczywiście, jeśli masz tylko kontekst pracowników i kontekst oknie można wykonać testy odwrotnych do kontekstu okiennej. Np. this.Window === undefined.

+0

Nie używaj przestarzałego '__proto__'. Użyj albo 'Object.getPrototypeOf()', albo po prostu '.isPrototypeOf' lub' instanceof'. – Bergi

Powiązane problemy