【问题标题】:Any standard mechanism for detecting if a JavaScript is executing as a WebWorker?检测 JavaScript 是否作为 WebWorker 执行的任何标准机制?
【发布时间】:2018-07-25 02:41:03
【问题描述】:

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

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

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

FileReaderSync
FileException
WorkerLocation
importScripts
openDatabaseSync
webkitRequestFileSystemSync
webkitResolveLocalFileSystemSyncURL

Detecting WorkerLocation 似乎是一个可行的候选方案,但这仍然让人觉得有点骇人听闻。有没有更好的办法?

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

【问题讨论】:

  • 你为什么不能只检查window
  • !(typeof window == "object" && typeof document == "object" && window.document === document) 怎么样?

标签: javascript html web-worker


【解决方案1】:

spec 说:

DOM API(Node 对象、Document 对象等)在本规范的这个版本中不适用于工作人员。

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

【讨论】:

    【解决方案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..
    

    【讨论】:

      【解决方案3】:

      这对我有用

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

      【讨论】:

        【解决方案4】:

        这对我有用:

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

        【讨论】:

        • 但它会抛出一个 selfWindow 都未定义的工人?
        • 哦,你是对的,但Window 仍然是undefined 并且instanceof 会因此而抛出。
        • @Bergi,是的,它会抛出一个错误。不过可以从那里继续。
        【解决方案5】:

        还有更多: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

        【讨论】:

        • 请不要使用已弃用的__proto__。使用Object.getPrototypeOf(),或仅使用.isPrototypeOfinstanceof
        猜你喜欢
        • 2014-08-24
        • 1970-01-01
        • 1970-01-01
        • 2023-03-29
        • 2010-09-17
        • 2015-06-08
        • 1970-01-01
        • 2020-08-08
        • 1970-01-01
        相关资源
        最近更新 更多