У меня есть Web Worker. Я хочу сделать с ней периодические сетевые запросы. Одна вещь, которую я особенно хочу, это сделать эти запросы, даже если основной поток выполнения JS заблокирован (например, с помощью window.alert). Я использую Chrome 38.Веб-рабочий заблокирован основной нитью в Chrome
Однако, когда я пытаюсь выполнить сетевые запросы у рабочего, запросы, по-видимому, блокируются потоком пользовательского интерфейса. Вот надуманный пример, чтобы проиллюстрировать эту проблему:
base.js:
var worker = new Worker("/worker.js");
setTimeout(function() {
console.log("begin blocking");
var startDt = new Date();
var blockPeriod = 5000;
var a;
// Obviously we'd never actually do this, but this while loop
// is a convenient way to create the problem case (a blocked main
// thread).
while ((new Date() - startDt) < blockPeriod) {
a = 0;
}
console.log("stop blocking");
}, 3000);
worker.js:
var requestInterval = 1000;
var sendRequest = function() {
console.log("Send request interval");
var request = new XMLHttpRequest();
request.open("GET", "/ping", true);
request.onload = function() {
if (request.status === 200){
console.log(request.responseText)
} else {
console.log(request.status)
}
};
request.onerror = function() {
console.log("error")
};
request.send();
setTimeout(sendRequest, requestInterval);
}
sendRequest();
В результате я вижу в том, что мы видим успешные запросы HTTP для три секунды, пока не начнется блокировка. На данный момент мы не видим ничего, не вошли в консоль до блокирующих концов, в какой момент мы видим пять «Интервал отправки запроса» ы затем 5 журналов ответа, например:
Send request interval
{"pong": true}
Send request interval
{"pong": true}
Send request interval
{"pong": true}
Send request interval
{"pong": true}
begin blocking
stop blocking
5x Send request interval
5x {"pong": true}
Send request interval
{"pong": true}
I также см. в журналах моего сервера, что в это время блокировки не поступают запросы, затем все пять запросов принимаются примерно одновременно в конце периода блокировки.
Учитывая, что «Интервал запроса на запрос» встречается пять раз подряд, рабочий, по-видимому, продолжает выполнять: если бы это было не так, это не пропустило бы очередь на очередную итерацию. Я также обнаружил, что если я заблокирую, запустив window.alert вместо вращения в цикле, я получаю сообщения журнала с начала sendRequest
с интервалом в 1 секунду, а затем получаю сообщения журнала обработчика ответа в большой партии в виде как только я прекращу блокировку.
В Firefox фоновый поток, кажется, полностью останавливается в этом случае (я не получаю ту же самую партию из пяти запросов, стоящих в очереди в течение заблокированного периода). Однако в этом случае я ориентируюсь только на Chrome (и в конечном итоге хочу использовать WebSockets, которые даже не работают в Firefox Workers), поэтому меня это не очень интересует.
Все это добавляет, что это приводит меня к мысли, что есть некоторые классы активности в веб-работниках, которые блокируются нерестовым потоком, а некоторые из них не являются (я изначально видел такое же поведение с помощью WebSockets). Конкретно, я хотел бы знать (если кто-то знает):
- Активность рабочего заблокирована основной нитью в Chrome?
- Есть ли способ обойти это? Мне очень хотелось бы иметь возможность установить соединение WebSocket у Рабочего, а затем продолжить PING/PONG туда и обратно, даже если что-то (например, предупреждение/подтверждение) блокирует основной поток.
- Это все чепуха, и я просто делаю что-то глупое?
Да, это [похоже, цикл событий не останавливается] (http://stackoverflow.com/a/2734311/1048572) во время «предупреждения» :-) – Bergi
Берги, спасибо за ответ. Однако вся идея веб-работников заключается в том, что они работают в фоновом потоке и не мешают пользовательскому интерфейсу (bobince даже упоминает это оговорку в ответе, на который вы ссылались). И это, очевидно, в какой-то мере: приведенные выше примеры показывают, что в какой-то степени они выполняются, даже когда основной поток блокируется. Мой большой вопрос в том, где линия находится между тем, что есть и не заблокировано основным потоком. – heliotrope
«Неблокирование не обязательно означает одновременное». Исходная статья: http://code.tutsplus.com/tutorials/getting-started-with-web-workers--net-27667 – sergolius