Я работаю над веб-приложением с закрытой системой, чтобы помочь компаниям в их повседневной работе по онлайн-торговле. Это означает, с одной стороны, что он не будет открыт для публики, с другой: ему придется иметь дело с большими объемами данных, сохраняя при этом свободный опыт работы.
Вот почему я обратился к веб-работникам в 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.
Я что-то упустил здесь? Любое понимание будет оценено, так как я новичок в этой концепции веб-работников.
Спасибо 🙂
Вашему вопросу не хватает ресурсов, чтобы по-настоящему понять, что именно идет не так. Я могу согласиться с этим два веб-работника могут работать одновременно, даже при синхронных операциях. Я проверил это для обоих for
зацикливает и синхронизирует запросы XHR.
Хотя я бы порекомендовал несколько вещей.
Первый — если вы не обрабатываете данные с использованием какого-либо сложного алгоритма ЦП, веб-работники — пустая трата времени Запросы XHR не блокируют основной поток (если вы явно не попросите их об этом).
statusCheck()
ты заявляешь var w__statusCheck
что означает локальную переменную. Поэтому он всегда будет нулевым, как видно из внешней области видимости. Это может привести к сборке мусора, если на рабочем месте не запущен код.XMLHttpRequest.onreadystatechange
, использование onload
а также onerror
,stringify
данные, которые вы публикуете для веб-работника. Это уже сделано для вас браузером, возможно, более оптимальным способом. Преобразование данных во что-то — самая распространенная глупость, которую люди делают с веб-работниками.Также при публикации вопроса, по крайней мере, убедитесь, что код имеет какой-то смысл. В вашем посте фигурные скобки не совпадают.
Хорошо .. Я понял это:
Я искал во всех неправильных местах. Оказывается, я инициализировал сеанс php во всех сценариях php, которые вызываются рабочими. И мои два параллельных работника оба назвали одного. Таким образом, файл сеанса был заблокирован первым сценарием php, а второму пришлось подождать, пока он снова не откроется снова. Это не рабочие или JS мешали, это был php.
Я теперь взял инициализацию сеанса из моего statusCheck.php, и он работает как шарм. Я сохраню это в тех других, которые обрабатывают ответы пользовательского ввода, потому что там это действительно имеет смысл: пользователь нажимает на кнопку «Скомпилировать данные XY», которая выполняется рабочим и занимает некоторое время. Как бы он ни был нетерпелив, он уже нажимает следующую кнопку «показать эти данные» … и из-за заблокированного файла сеанса у меня есть какая-то аккуратная очередь для этих действий. 🙂
Я все еще приму вышеизложенные рекомендации и позабочусь о том, чтобы улучшить мой код. 🙂