Any standard mechanism for detecting if a JavaScript is executing as a WebWorker?

浪尽此生 提交于 2019-11-28 23:23:45

The spec says:

The DOM APIs (Node objects, Document objects, etc) are not available to workers in this version of this specification.

This suggests checking for the absence of document is a good way to check you're in a worker. Alternatively you could try checking for the presence of WorkerGlobalScope?

Although post a bit old, adding a couple of generic alternatives What is used in Asynchronous.js library (a library for generic handling of asynchronous/parallel processes, author) is the following:

// 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..

this works for me:

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

This worked for me

  if (self.document) {
    console.log('We are calculating Primes in Main Thread');
  } else {
    console.log('We are calculating Primes in Worker Thread');
  }

There's even more: WorkerNavigator etc.

Unless there's a keyword to detect webworkers, you got to use a variable. (Nothing can stop a rogue script running before your script from setting or replacing variables. )

So, assuming you do not have any rogue scripts running before your script, any of these lines will work:

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)

You can also use self § instead of this, but since this can't be set, its neater.


I prefer:

this.DedicatedWorkerGlobalScope !== undefined

Of course, if you only have worker context and window context, you can do the inverse tests for window context. Eg this.Window === undefined.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!