Надежно определите, выполняется ли script у веб-мастера
В настоящее время я пишу небольшую библиотеку в JavaScript, чтобы помочь мне делегировать веб-работнику некоторые тяжелые вычисления.
По некоторым причинам (в основном, для возможности отладки в потоке пользовательского интерфейса, а затем запускать один и тот же код у рабочего), я бы хотел определить, выполняется ли script в рабочем или в потоке пользовательского интерфейса.
Я не опытный разработчик JavaScript, и я хотел бы убедиться, что следующая функция будет надежно обнаруживать, есть ли у меня рабочий или нет:
function testenv() {
try{
if (importScripts) {
postMessage("I think I'm in a worker actually.");
}
} catch (e) {
if (e instanceof ReferenceError) {
console.log("I'm the UI thread.");
} else {
throw e;
}
}
}
Итак, не так ли?
Ответы
Ответ 1
Как уже отмечалось, есть ответ в другом потоке, который говорит, чтобы проверить наличие объекта документа в окне. Я хотел, однако, внести изменения в свой код, чтобы избежать выполнения блока try/catch, который замедляет выполнение JS в Chrome и, вероятно, в других браузерах также.
EDIT: ранее я сделал ошибку, предположив, что в глобальном масштабе есть объект окна. Обычно я добавляю
//This is likely SharedWorkerContext or DedicatedWorkerContext
window=this;
в верхней части моего рабочего загрузчика script это позволяет всем функциям, которые используют обнаружение функций окна, не взорваться. Затем вы можете использовать функцию ниже.
function testEnv() {
if (window.document === undefined) {
postMessage("I'm fairly confident I'm a webworker");
} else {
console.log("I'm fairly confident I'm in the renderer thread");
}
}
В качестве альтернативы без назначения окна при условии, что он находится на уровне верхнего уровня.
var self = this;
function() {
if(self.document === undefined) {
postMessage("I'm fairly confident I'm a webworker");
} else {
console.log("I'm fairly confident I'm in the renderer thread");
}
}
Ответ 2
Довольно поздно к игре на этом, но здесь лучший, самый пуленепробиваемый способ, которым я мог бы придумать:
// run this in global scope of window or worker. since window.self = window, we're ok
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
// huzzah! a worker!
} else {
// I'm a window... sad trombone.
}
Ответ 3
Emscripten делает:
// *** Environment setup code ***
var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
var ENVIRONMENT_IS_WEB = typeof window === 'object';
var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
(Emscripten on Github)