2011-10-28 17 views
10

Attualmente sto scrivendo una piccola libreria in JavaScript per aiutarmi a delegare a un web-worker alcuni calcoli pesanti.Rilevare attendibilmente se lo script è in esecuzione in un web worker

Per alcuni motivi (principalmente per la possibilità di eseguire il debug nel thread dell'interfaccia utente e quindi eseguire lo stesso codice in un worker) vorrei rilevare se lo script è attualmente in esecuzione in un worker o nel thread dell'interfaccia utente.

Io non sono uno sviluppatore JavaScript stagionato e vorrei assicurare che la seguente funzione in modo affidabile rilevare se sono in un operaio o no:

function testenv() { 
    try{ 
     if (importScripts) { 
      postMessage("I think I'm in a worker actually."); 
     } 
    } catch (e) { 
     if (e instanceof ReferenceError) { 
      console.log("I'm the UI thread."); 
     } else { 
      throw e; 
     } 
    } 
} 

Quindi, lo fa?

+0

'e se e instanceof ReferenceError' deve generare un errore di sintassi. –

+0

Era specifico per Firefox, ora risolto. – thomas

+0

Domanda correlata (senza risposta, però): [Esiste un meccanismo standard per rilevare se un JavaScript è in esecuzione come WebWorker?] (Http://stackoverflow.com/questions/7507638/is-there-a-standard- meccanismo-per-rilevare-se-un-javascript-è-esecuzione-come-un-noi) –

risposta

8

Come indicato c'è una risposta in another thread che dice di verificare la presenza di un oggetto documento sulla finestra. Volevo comunque apportare una modifica al codice per evitare di eseguire un blocco try/catch che sia slows execution of JS in Chrome e probabilmente anche in altri browser.

MODIFICA: in precedenza ho commesso un errore nell'assumere che esistesse un oggetto finestra nell'ambito globale. Io di solito aggiungere

//This is likely SharedWorkerContext or DedicatedWorkerContext 
window=this; 

alla parte superiore del mio script loader worker questo permette tutte le funzioni che utilizzano il rilevamento funzione finestra per non saltare in aria. Quindi puoi usare la funzione qui sotto.

function testEnv() { 
    if (window.document === undefined) { 
    postMessage("I'm fairly confident I'm a webworker"); 
    } else { 
    console.log("I'm fairly confident I'm in the renderer thread"); 
    } 
} 

In alternativa senza l'assegnazione della finestra purché nella sua portata di livello superiore.

var self = this; 
function() { 
    if(self.document === undefined) { 
    postMessage("I'm fairly confident I'm a webworker"); 
    } else { 
    console.log("I'm fairly confident I'm in the renderer thread"); 
    } 
} 
+0

Grazie per il fatto che un tentativo/cattura dovrebbe essere evitato. Come per un motore di gioco giocattolo che codifico, la velocità è un aspetto importante per me. – thomas

+0

Si noti che "self" è attualmente disponibile per impostazione predefinita negli utenti Web https://developer.mozilla.org/en/docs/Web/Guide/Performance/Using_web_workers –

+0

@JamiePate, anche "questo" funziona. Vedere https://stackoverflow.com/a/45657328/632951 – Pacerier

24

abbastanza tardi per il gioco su questo, ma qui è il modo migliore, più bulletproofy potevo venire con:

// run this in global scope of window or worker. since window.self = window, we're ok 
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) { 
    // huzzah! a worker! 
} else { 
    // I'm a window... sad trombone. 
} 
+0

Would: if (self.WorkerGlobalScope) {} else {} funziona allo stesso modo? Finché nessuno ha aggiunto WorkerGlobalScope al progetto ... sembra efficace e conciso. –

+1

Sì, è possibile, ma sono andato con il doppio controllo perché è più affidabile che sperare che qualcuno non scriva su 'self.WorkerGlobalScope' (che è generalmente improbabile, ma preferisco l'impostazione predefinita a più bulletproof) – borbulon

+0

funziona per me: auto instanceof Window – mbelow

9

Emscripten fa:

// *** Environment setup code *** 
var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function'; 
var ENVIRONMENT_IS_WEB = typeof window === 'object'; 
var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; 
var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER; 

(Emscripten on Github)

+0

Si potrebbe anche voler controllare [questa risposta] (http://stackoverflow.com/a/33697246/304175) da @NikosM per vedere cosa fa Asynchronous.js. – skalee

Problemi correlati