Любой стандартный механизм для определения того, выполняется ли JavaScript в качестве WebWorker?

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

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

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

FileReaderSync
FileException
WorkerLocation
importScripts
openDatabaseSync
webkitRequestFileSystemSync
webkitResolveLocalFileSystemSyncURL

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

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

Ответы

Ответ 1

spec говорит:

API-интерфейсы DOM (объекты 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 instanceof Window) {
    // not in worker
}

Ответ 4

Там еще больше: WorkerNavigator и т.д.

Если нет ключевого слова для обнаружения веб-мастеров, вы должны использовать переменную. (Ничто не может остановить изгоев script, запущенных до того, как ваш script установит или заменит переменные.)

Итак, предположим, что у вас нет каких-либо скриптов-жуликов, запущенных до вашего script, любая из этих строк будет работать:

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 & sect; вместо this, но поскольку this не может быть установлен, его аккуратнее.


Я предпочитаю:

this.DedicatedWorkerGlobalScope !== undefined

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