Надежно определите, выполняется ли 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)