Можно ли как-то загрузить класс в webworker вместо простого файла javascript? - PullRequest
1 голос
/ 31 мая 2019

Я хочу загрузить файл в webworker, но это не простой файл javascript.Это класс.Таким образом, вместо записи URL файла JavaScript в новом Worker (filename.js);

Я инициализирую класс написанием нового Worker (new ClassName ());

Он читает файл и загружает его правильно.Он даже показывает сообщение console.log в конструкторе.Но когда элемент управления перемещается в метод postMessage в основном файле, он выдает ошибку.

Приложение, над которым я работаю, имеет очень сложную структуру.У нас есть общий модуль, который содержит несколько классов, которые выполняют некоторые общие функции по всему приложению.Функциональность, над которой я работаю, может вызвать проблемы с производительностью, если я выполню ее непосредственно в приложении.Итак, я загружаю его в веб-работника.Так как это класс, поэтому я должен вызывать его, используя новое ключевое слово.Поэтому вместо:

var ww = new Worker(filename.js);

я пишу:

var ww = new Worker(new ClassName());

Теперь он вызывает класс, он записывает в журнал оператор, написанный в конструкторе, но когда в основном файле он выполняет postMessagejavascript выдает ошибку и останавливает выполнение метода.

См. код ниже:

mainFile.js

    var ww = new Worker(new CommonWebWorker());
        ww.postMessage('LOAD');
        ww.onmessage = function (e) {
            console.log(e.data);
    }

CommonWebWorker.js

'use strict';

class CommonWebWorker {
    constructor() {
        console.log("commonWebWorker invoked");
        this.onmessage = function (e) {
            this.postMessage((e.data === 'LOAD' ? 'Loading...' : 'Loading Error'));
        }
    }
}

module.exports = CommonWebWorker;

Я ожидаю, что файл будет загружаться в фоновом режиме через WebWorker, но на самом деле он ломается и выбрасывает приведенную ниже ошибку

GET http://localhost:3000/[object%20Object] 404 (Не найдено)

Любойвид помощи очень ценится.

1 Ответ

3 голосов
/ 31 мая 2019

Причина ошибки в том, что Worker ожидает строку URL в качестве первого параметра, а не объекта. Таким образом, он преобразует его в строку, и когда вы делаете это для большинства объектов, вы получаете "[object Object]" (хотя я ожидал бы "[object CommonWebWorker]" из вашего кода, но я предполагаю, что вы используете транспилятор или что-то, выводящее код ES5, который даст вам "[object Object]" вместо).

Ваша главная страница и ваша работа - это совершенно разные среды JavaScript. Вы, конечно, можете использовать класс в своем работнике, если хотите, но вам нужно будет создать его экземпляр в работнике, например ::100100

class CommonWebWorker {
 // ...
}
new CommonWebWorker(); // To instantiate it

Ваш работник также может импортировать class из другого файла JavaScript с помощью importScripts (в скором времени он сможет использовать вместо него синтаксис модуля ES2015 +), поэтому, если вы хотите использовать один и тот же класс в нескольких рабочих, вы можете поместить его в свой собственный файл и сделать:

importScripts("common-web-worker.js");
new CommonWebWorker(); // To instantiate it

Как только синтаксис ES2015 + станет широко доступным для работников¹, вы начнете своего работника с соответствующим флагом модуля (new Worker("worker.js", {type: "module"})) и сделаете это вместо этого:

import CommonWebWorker from "./common-web-worker.js";
new CommonWebWorker();

checked Я проверил около месяца назад, и единственным браузером, поддерживающим его, был Chrome с флагом --enable-experimental-web-platform-features. Но этот материал быстро меняется ...: -)

...