Вот мое лучшее предположение о том, что происходит. Публикуя сообщение от Web Worker каждые 1 мс, вы требуете, чтобы основной поток обрабатывал каждое отправленное сообщение в течение 1 мс.
Если основной поток не способен обработать сообщение в течение 1 мс, вы по-прежнему отправляете ему новое сообщение, даже если оно не закончило обработку последнего сообщения. Я бы предположил, что это помещает его в очередь сообщений, ожидающих обработки.
Теперь, поскольку вы отправляете сообщения от веб-рабочего быстрее, чем их можно обработать, эта очередь необработанных сообщений будет становиться все больше и больше. В какой-то момент Chrome собирается взломать руки и сказать: «В очереди слишком много сообщений», и вместо очередей новых сообщений для обработки он их отбрасывает.
Именно поэтому, если вы используете разумное число в тайм-ауте, таком как 100 мс, сообщение имеет достаточно времени для обработки до отправки следующего сообщения, и никаких проблем с необработанными сообщениями не возникает.
Я создал jsFiddle, где работник отправляет сообщение в основной поток, а основной поток отправляет сообщение обратно к работнику. Если этот процесс не будет выполняться до отправки следующего сообщения, счетчики в обоих потоках будут несовместимы, и веб-рабочий завершится.
http://jsfiddle.net/meovfpv3/3/
Вы можете видеть, что при разумном SetTimeout 100 мс, все сообщения имеют достаточно времени, чтобы обработать до появления следующего сообщения.
Когда вы опускаете setTimeout до 1 мс, цепочка сообщений не успевает закончить до того, как будет отправлено следующее сообщение, и счетчики в каждом потоке в конечном итоге будут рассортированы, отключив пункт 10 и прекратив работу веб-рабочего.
Одним из способов решения этой проблемы является вместо того, чтобы слепо отправлять сообщения каждый 1мс ли последний было обработана или нет, только опубликовать новое сообщение после того, как вы получили сообщение от главной темы. Это означает, что вы отправляете сообщения только так быстро, как основной поток может их обрабатывать.
Для полноты здесь есть копия JSFiddle code:
работник:
var counter2 = 0;
var rcvd = true;
function hi() {
counter2++;
console.log("")
console.log("postMessage", counter2)
postMessage(counter2);
if (!rcvd) {
self.close();
console.log("No message received");
}
rcvd = false;
setTimeout(hi, 1);
}
hi();
onmessage = function(e) {
rcvd = true;
console.log("secondMessage", e.data);
}
Главная:
var ww = document.querySelector('script[type="text/ww"]'),
code = ww.textContent,
blob = new Blob([code], {type: 'text/javascript'}),
blobUrl = URL.createObjectURL(blob),
worker = new Worker(blobUrl),
counter = 0;
worker.onmessage = function(e) {
counter++;
console.log("onmessage:", counter);
worker.postMessage(e.data);
}
Конечно, мы можем объяснить, почему, но не просим нас угадать. Вам нужно будет показать ** минимальный проверяемый пример **, чтобы мы могли проверить его. –
@ IsmaelMiguel Я обновил вопрос с помощью кода worker.js. В основном я делаю blob из строки и отдаю ее работнику –
У меня такая же проблема. Я обнаружил, что Рабочие не заканчиваются (тестируются с помощью 'console.log'), обратный вызов onmessage просто перестает быть запущенным в какой-то момент. Очень странное и неприемлемое поведение браузера! * table flip * –