#javascript
Есть некоторая функция, которая может отработать за несколько секунд, а может черт знает за сколько. Хочется обернуть ее во что-нибудь, что прервет ее выполнение через, например, минуту. Вроде бы представляю, как сделать это с потоками. На каком-нибудь другом языке. На JS не получается. Мысль идет в следующем направлении: function avoidAfterTime() { var startTime = new Date().getTime(); var interval = setInterval(function () { if (new Date().getTime() - startTime > 3000) { clearInterval(interval); console.log("more than ? sec") return; } longWorking(); }, 2000); } avoidAfterTime(); function longWorking(){ var t; for (i = 0; i < 1e10; i++) t = i; console.log(t); }
Ответы
Ответ 1
В JavaScript, как верно подметил @Darth, есть такая штука как Worker. Фактически он является объектом, выполняющим действия в параллельном потоке, не мешая основному потоку, обрабатывающему страницу браузера. Из основного потока им можно управлять, в том числе создавать и разрушать. Вот пример простейшего воркера, иллюстрирующий основы обращения с ним, думаю, разберётесь. (В сниппете работать не будет, поэтому простым кодом.) worker.html
worker.js var counter = 0; self.addEventListener('message', function(event) { switch (event.data) { case 'start': setInterval(function(){ self.postMessage(++counter); }, 100); break; default: ; } console.log(data); }, false); Есть некоторые ограничения на использование воркера. Во-первых, весь код воркера должен лежать в отдельном файле. А во-вторых, если попытаться запустить этот пример в Google Chrome из локального файла, то воркер работать не будет, а в консоли появится ошибка Uncaught SecurityError: Failed to construct 'Worker': Script at 'file:///ПУТЬ_ДО_ФАЙЛА/worker.js' cannot be accessed from origin 'null'. Если запускать с http-сервера, то работает. Впрочем, IE и Firefox нормально работают и с файлами.Ответ 2
Js конечно однопоточный, как верно подметил @Grundy. Но есть такая штука, как Worker. Вы можете запускать свою функцию в воркере и просто прибивать его, когда он вам надоест с помощью Worker.terminate();.Ответ 3
Кроме предложенных воркеров, которые отлично подходят для тяжелых вычислений, можно еще воспользоваться другим методом. Если это позволяет алгоритм, можно разбить выполнение тяжелой ф-ции на некоторые части (если это обработка изображения, и она допускает обработку картинки по частям, то можно скармливать 10 раз десятую часть картинки за раз, например). Если составить алгоритм таким образом, что он будет принимать на вход небольшие порции данных, а в конце складывать все по кусочкам (как пример, обработка звукового потока), то во время приема нового кусочка данных можно проверять условие на остановку выполнения (можно или нельзя продолжать). В некоторых случаях этого будет достаточно. Кроме того, такой подход можно применить и в воркере.
Комментариев нет:
Отправить комментарий