javascript — одновременные запуски двух веб-работников JS: один застревает

Я работаю над веб-приложением с закрытой системой, чтобы помочь компаниям в их повседневной работе по онлайн-торговле. Это означает, с одной стороны, что он не будет открыт для публики, с другой: ему придется иметь дело с большими объемами данных, сохраняя при этом свободный опыт работы.

Вот почему я обратился к веб-работникам в JS для запуска всех видов доступа к базам данных и загрузки данных в фоновом режиме.
Насколько я понимаю, не только основной пользовательский интерфейс / основной JS остается непрерывным, но и различные веб-работники работают, не мешая друг другу.

Теперь у меня есть следующие настройки:

mainJS: функция statusCheck, которая запускается при загрузке страницы:

function statusCheck() {
if(typeof(w__statusCheck) == "undefined") {
var w__statusCheck = new Worker("...statusCheck.js");
w__statusCheck.postMessage("go");
w__statusCheck.onmessage = function(e) {
var message = JSON.parse(e.data);
if(message.text!=undefined) displayMessage(message.text);
}
}

statusCheck.js который рабочий просто выглядит так:

function checkStatus() {
console.log("statusCheck started");
// I will leave standard parts out:
// creating and testing the ajax variable against different browsers

ajaxRequest.onreadystatechange = function() {
if(ajaxRequest.readyState == 4) {
self.postMessage(ajaxRequest.responseText);

var timer;
timer = self.setTimeout(function(){
checkStatus();
}, 1000);
}
}

ajaxRequest.open("GET", "...worker_statusCheck.php", true);
ajaxRequest.send(null);
}

this.onmessage = function(e){
checkStatus();
};

Как видите, это перезапускается каждую секунду (пока). Интервал может быть дольше в производстве.
worker_statusCheck.php просто получает разные вещи из базы данных и связывает их в объект JSON, который дает мне статус системы.

Это прекрасно работает.

Теперь у меня есть другой работник, который должен быть инициирован нажатием на ссылку, чтобы эффективно вызывать php для выполнения действий:
mainJS loadWorker

function loadWorker(url="") {
console.log("loadWorker started");

if(url!="") {
var uniqueID = "XXX" // creating a random ID based on timestamp and Math.random()

if(typeof(window[uniqueID]) == "undefined") {
var variables = { ajaxURL: url };
window[uniqueID] = new Worker("....loadWorker.js");
window[uniqueID].postMessage(JSON.stringify(variables));
window[uniqueID].onmessage = function(e) {
var message = JSON.parse(e.data);
if(message["success"]!=undefined) {
variables["close"] = "yes";
window[uniqueID].postMessage(JSON.stringify(variables));
}
}
}

При каждом щелчке по определенной ссылке вызывается это, создается работник с уникальным именем, запускается, получает данные и сообщает работнику close(),

Php снова делает свое дело и записывает обновление прогресса в БД после каждого шага длительной процедуры. Эти обновления прогресса я получаю из БД с помощью повторяющейся проверки состояния выше.

Теперь я могу видеть записи в БД с отметкой времени, поэтому я знаю, что они записываются каждый в свое время.
Итак, оба работника выполняют свою работу и работают надежно. Но я заметил, что всякий раз, когда я запускаю работника, работающего вручную (с произвольным именем), statusCheck фактически прекращает выполнение. Это просто застревает … Я смог подтвердить это с помощью вывода консоли от обоих рабочих. Так что это не основной JS, который кажется застрявшим, но statusCheck на самом деле делает паузу … и возобновляет работу после завершения loadWorker.

Я что-то упустил здесь? Любое понимание будет оценено, так как я новичок в этой концепции веб-работников.

Спасибо 🙂

0

Решение

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

Хотя я бы порекомендовал несколько вещей.

Первый — если вы не обрабатываете данные с использованием какого-либо сложного алгоритма ЦП, веб-работники — пустая трата времени Запросы XHR не блокируют основной поток (если вы явно не попросите их об этом).

  1. В statusCheck() ты заявляешь var w__statusCheck что означает локальную переменную. Поэтому он всегда будет нулевым, как видно из внешней области видимости. Это может привести к сборке мусора, если на рабочем месте не запущен код.
  2. Не использовать XMLHttpRequest.onreadystatechange, использование onload а также onerror,
  3. Случайные уникальные идентификаторы для переменных почти всегда неверны. Если вам вообще нужно сохранить ссылку на работника, либо дайте ему разумное имя (например, URL, который он должен загрузить), либо используйте инкрементный идентификатор.
  4. Делать НЕ stringify данные, которые вы публикуете для веб-работника. Это уже сделано для вас браузером, возможно, более оптимальным способом. Преобразование данных во что-то — самая распространенная глупость, которую люди делают с веб-работниками.

Также при публикации вопроса, по крайней мере, убедитесь, что код имеет какой-то смысл. В вашем посте фигурные скобки не совпадают.

0

Другие решения

Хорошо .. Я понял это:
Я искал во всех неправильных местах. Оказывается, я инициализировал сеанс php во всех сценариях php, которые вызываются рабочими. И мои два параллельных работника оба назвали одного. Таким образом, файл сеанса был заблокирован первым сценарием php, а второму пришлось подождать, пока он снова не откроется снова. Это не рабочие или JS мешали, это был php.

Я теперь взял инициализацию сеанса из моего statusCheck.php, и он работает как шарм. Я сохраню это в тех других, которые обрабатывают ответы пользовательского ввода, потому что там это действительно имеет смысл: пользователь нажимает на кнопку «Скомпилировать данные XY», которая выполняется рабочим и занимает некоторое время. Как бы он ни был нетерпелив, он уже нажимает следующую кнопку «показать эти данные» … и из-за заблокированного файла сеанса у меня есть какая-то аккуратная очередь для этих действий. 🙂

Я все еще приму вышеизложенные рекомендации и позабочусь о том, чтобы улучшить мой код. 🙂

-1

По вопросам рекламы [email protected]