Любой стандартный механизм для определения того, выполняется ли 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
.