HTML5 / Решение проблемы importScripts() в Opera

в 12:37, , рубрики: html5, метки:

Доброго всем времени суток! Буквально сегодня при использовании Web Workers столкнулся с проблемой в функции importScripts(), которая заключается в том, что Opera(использую версию 11.61) по каким-то своим внутренним причинам при повторном создании объекта Worker отказывается исполнять внутри него функцию importScripts()(проблема возникает только в опере, остальные браузеры ведут себя адекватно).

Небольшой пример:

  var str = "http://" + document.domain + "/classes/js/workers/worker.js";  var worker = new Worker(str);  worker.onerror = function(e)  {      alert([      'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message].join(''));  }    worker.onmessage = function (obj)  {      alert(obj['data']);  }    worker.postMessage();  

код воркера(предположим, что в some.js у нас есть глобальная переменная test):

  onmessage = function ()  {      importScripts("/classes/js/some.js");      postMessage(test);  }  

Приведенный выше код при первом вызове добросовестно выведет нам содержимое переменной test, но вот повторный вызов вместо ожидаемого значения выведет ошибку о том, что переменная test не определена. По каким именно причинам повторно не выполняется importScripts про то неведомо. Поборовшись несколько часов, нашел решение. Все просто, раз уж опера не хочет повторно импортировать скрипты во вновь созданном объекте, то новый объект создавать и не будем, создадим всего один и сделаем его глобальным и в дальнейшем будем все слать через него. Предыдущий код можно модернизировать следующим образом:

  if(!('worker' in window))  {      var str = "http://" + document.domain + "/classes/js/workers/worker.js";      worker = new Worker(str);      worker.onerror = function(e)      {          alert([          'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message].join(''));      }  }  worker.onmessage = function (obj)  {      alert(obj['data']);  }    worker.postMessage();  

при этом обработчик onmessage не стоит помещать внутрь условия, так как если внутри него будут использоваться переменные приходящие в функцию, то будет создано замыкание на переменные первого вызова, а последующие будут игнорироваться.
Надеюсь, что баг с importScripts скоро пофиксят, все-таки технология еще свежа и порой ощущаешь себя бэта-тестером, а не пользователем…

P.S надеюсь, заметка будет кому-то полезна

Автор: Slavenin999


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js