有任何标准机制可以检测 JavaScript 是否作为 WebWorker 执行?

问题描述 投票:0回答:6

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

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

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

FileReaderSync
FileException
WorkerLocation
importScripts
openDatabaseSync
webkitRequestFileSystemSync
webkitResolveLocalFileSystemSyncURL

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

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

javascript html web-worker
6个回答
17
投票

规格说:

在此版本的规范中,DOM API(节点对象、文档对象等)对工作人员不可用。

这表明检查是否存在

document
是检查您是否属于工人的好方法。或者,您可以尝试检查是否存在
WorkerGlobalScope


4
投票

虽然帖子有点旧,但添加了一些通用替代品 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
投票

这对我有用

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

1
投票

这对我有用:

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

0
投票

我知道这是一个旧方法,但我没有看到这个方法,但我更喜欢它。其他人也可能。

“navigator”在 Workers 和 Windows 中都存在,但类型名称分别为“WorkerNavigator”和“Navigator”。

const inWorker = navigator.constructor.name === 'WorkerNavigator';

我喜欢这种方法,因为库有时可以向工作全局范围添加假“文档”对象或其他对象,以使其他有问题的库正常工作。此方法避免使用可能创建的虚拟变量来欺骗脚本。


-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上下文和window上下文,你可以对window上下文进行逆向测试。例如

this.Window === undefined

© www.soinside.com 2019 - 2024. All rights reserved.