18

WebWorker 的执行范围与传统 JavaScript 的“窗口”上下文完全分离。脚本是否有标准方法来确定它本身是否作为 WebWorker 执行?

我能想到的第一个“黑客”是检测工人范围内是否存在“窗口”属性。如果不存在,这可能意味着我们正在作为 WebWorker 执行。

其他选项是检测标准“窗口”上下文中不存在的属性。对于 Chrome 14,此列表当前包括:

FileReaderSync
FileException
WorkerLocation
importScripts
openDatabaseSync
webkitRequestFileSystemSync
webkitResolveLocalFileSystemSyncURL

检测 WorkerLocation 似乎是一个可行的候选者,但这仍然感觉有点骇人听闻。有没有更好的办法?

编辑:是我用来确定正在执行的 WebWorker 中存在的属性的 JSFiddle,这些属性现在位于“窗口”中。

4

5 回答 5

15

规范说:

在本规范的这个版本中,工作人员无法使用 DOM API(节点对象、文档对象等)。

这表明检查是否存在document是检查您是否在工作人员中的好方法。或者,您可以尝试检查是否存在WorkerGlobalScope?

于 2012-01-09T08:05:59.450 回答
3

虽然帖子有点老了,但添加了几个通用的替代方案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..
于 2015-11-13T16:20:17.060 回答
1

这对我有用

  if (self.document) {
    console.log('We are calculating Primes in Main Thread');
  } else {
    console.log('We are calculating Primes in Worker Thread');
  }
于 2018-07-24T18:41:03.827 回答
0

这对我有用:

if (self instanceof Window) {
    // not in worker
}
于 2014-08-29T14:48:24.713 回答
-1

还有更多:WorkerNavigator等等。

除非有一个关键字来检测网络工作者,否则你必须使用一个变量。(没有什么可以阻止恶意脚本在您的脚本设置或替换变量之前运行。)

因此,假设您没有在您的脚本之前运行任何恶意脚本,那么这些行中的任何一个都将起作用:

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

当然,如果你只有worker context和window context,你可以对window context做逆向测试。例如this.Window === undefined

于 2017-08-13T05:15:22.277 回答