Любой стандартный механизм для обнаружения, если JavaScript выполняется как WebWorker? - PullRequest
15 голосов
/ 22 сентября 2011

WebWorker выполняется с областью, совершенно отдельной от контекста «окна» традиционного JavaScript. Существует ли стандартный способ для скрипта определить, выполняется ли он сам как WebWorker?

Первый «хак», о котором я могу подумать, - это определить, есть ли свойство «окна» в области видимости работника. Если отсутствует, это может означать, что мы выполняем как WebWorker.

Дополнительными параметрами будет обнаружение свойств, отсутствующих в стандартном контексте окна. Для Chrome 14 этот список в настоящее время включает в себя:

FileReaderSync
FileException
WorkerLocation
importScripts
openDatabaseSync
webkitRequestFileSystemSync
webkitResolveLocalFileSystemSyncURL

Обнаружение WorkerLocation кажется жизнеспособным кандидатом, но это все еще кажется немного хакерским. Есть ли способ лучше?

EDIT: Здесь - это JSFiddle, который я использовал для определения свойств, присутствующих в исполняющем WebWorker, которые теперь находятся в «окне».

Ответы [ 5 ]

14 голосов
/ 09 января 2012

spec говорит:

API DOM (объекты Node, объекты Document и т. Д.) Недоступны работникам в этой версии этой спецификации.1007 *

Это говорит о том, что проверка на отсутствие document - хороший способ проверить, работаете ли вы.В качестве альтернативы вы можете попробовать проверить наличие WorkerGlobalScope?

2 голосов
/ 13 ноября 2015

Хотя пост немного устарел, добавив пару общих альтернатив В библиотеке 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..
0 голосов
/ 24 июля 2018

Это сработало для меня

  if (self.document) {
    console.log('We are calculating Primes in Main Thread');
  } else {
    console.log('We are calculating Primes in Worker Thread');
  }
0 голосов
/ 13 августа 2017

Есть даже больше: 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

Конечно, если у вас есть только рабочий контекст и контекст окна, вы можете выполнить обратные тесты для контекста окна.Например, this.Window === undefined.

0 голосов
/ 29 августа 2014

это работает для меня:

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