WebWorker使用与传统JavaScript的“窗口”上下文完全分离的范围执行。是否有一种标准方法可以让脚本确定它本身是作为WebWorker执行的?
我能想到的第一个“黑客”是检测工人范围内是否存在“窗口”属性。如果不存在,这可能意味着我们正在作为WebWorker执行。
其他选项是检测标准“窗口”上下文中不存在的属性。对于Chrome 14,此列表目前包括:
FileReaderSync
FileException
WorkerLocation
importScripts
openDatabaseSync
webkitRequestFileSystemSync
webkitResolveLocalFileSystemSyncURL
检测WorkerLocation似乎是一个可行的候选人,但这仍然感觉有点hackish。有没有更好的办法?
编辑:Here是我用来确定执行WebWorker中现在位于“窗口”中的属性的JSFiddle。
答案 0 :(得分:14)
spec说:
此规范的此版本中的工作人员无法使用DOM API(节点对象,文档对象等)。
这表明检查document
的缺席是检查你是否在工人中的好方法。或者,您可以尝试检查是否存在WorkerGlobalScope
?
答案 1 :(得分:2)
虽然发布有点旧,但添加了几个通用替代品 Asynchronous.js库(用于异步/并行进程的通用处理的库,作者)中使用的内容如下:
// 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..
答案 2 :(得分:0)
这对我有用:
if (self instanceof Window) {
// not in worker
}
答案 3 :(得分:0)
这对我有用
if (self.document) {
console.log('We are calculating Primes in Main Thread');
} else {
console.log('We are calculating Primes in Worker Thread');
}
答案 4 :(得分:-1)
还有更多:WorkerNavigator
等。
除非有检测webworkers的关键字,否则必须使用变量。 (在脚本设置或替换变量之前,没有什么可以阻止运行的恶意脚本。)
因此,假设您在脚本之前没有运行任何流氓脚本,那么这些行中的任何一行都将起作用:
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)
您也可以使用self
§代替this
,但由于this
无法设置,因此无需设置。
我更喜欢:
this.DedicatedWorkerGlobalScope !== undefined
当然,如果您只有工作区上下文和窗口上下文,则可以对窗口上下文进行反向测试。例如this.Window === undefined
。