18

I have a few questions about web workers

  • Does the worker have access to storage? E.g. indexedDB/webSQL and local storage of the file the worker was initiated from?

  • How can i include a file in a worker? I have a functions.js which has alot of quick app related functions and it really wont make sense to copy paste the file's contents in a worker only to have two different places up update my functions.

  • Can I have a DOM inside a worker? like load an audio file in a temp audio tag to read its duration and if it is playable or not. Not access dom of parent page, but have a DOM in the worker itself.

  • If the answers to any of the question is negative then how can/should it be done manually?

This is for a chrome app so I have access to the latest Chrome APIs and I don't need to care about backward compatibility.

Achshar
  • 5,153
  • 8
  • 40
  • 70

2 Answers2

9

There is no DOM access of any kind from a web worker - period. ALL DOM manipulation must be done from the main JS thread. Web Workers can only communicate with the main thread via messaging.

This previous SO question tells you that web workers cannot access local storage, something that was easily found with a Google search.

That same thread has a list of what web workers can access.

It is unclear what you mean by "include a file in a worker". You can import scripts. I don't know what else you're asking about. You can use an ajax call to fetch data if that will help you with your audio file.

This sounds to me like you need to do some basic research about what you can and can't do with web workers (as there is a TON written about it on the web) and then come back with a lot more specific questions that incorporate that knowledge.

There are no hacks for web workers that let you do more than you are supposed to be able to do.

You can do work in the main JS thread and do it in little chunks with setTimeout if you have a lot of work to do and want to keep the main UI as responsive as possible. This is a very old design pattern that goes back to the days before threading was available or easy to use. It involves designing your work such that it can be done in little pieces with state stored in some persistent object and then you can repeatedly do small amounts of work and then return back, only to pick up the next piece of work on the next timer tick.

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • well yes but loading mp3s to audio tags takes alot of time. Workers were a possible solution to that but they don't have DOM. so how do you suggest i read the duration of files? and what about inclusion? a hack if inevitable.. :O – Achshar Sep 21 '11 at 06:21
  • well from include i meant `i have a functions.js which has alot of quick app related functions and it really wont make sense to copy paste the file's contents in a worker` (as explained in [1]) and yes `importScripts` is what i needed, thanks! from `hack` i meant some thing like reading a file's contents and adding them in eval. (yes i know that sounds bad, but it would have been a hack for a reason) that was until i read about importscripts. sorry if my question felt lame, as you can tell, i am new to workers.. :O – Achshar Sep 21 '11 at 06:37
  • I just expect people to do some simple research on Google before asking others to do the work for you. The thread I linked above was the very first hit in a Google search. I didn't know that answer, but looked it up in 5 seconds. Then, once you're armed with the basics or have specific questions about what you read, you can ask much more meaningful questions related to your problem. There are also many great articles about what you can and can't do with web workers and how they work that are much better for getting you started than we are. – jfriend00 Sep 21 '11 at 06:40
  • and as for why the websql question, of course i googled first but i was looking for 'web workers websql' localstorage i added just while writing the question. – Achshar Sep 21 '11 at 06:41
3

You can load a javascript library. See this example:

<body>
    <button>Start</button>
    <div id="output"></div>
    <script id="worker_1" type="text/js-worker">
        importScripts(base_url + '/worker_lib2.js');

        function run(event) {
            var msg = event.data;
            this.postMessage({ answer: hello(event.data.name)});
        }

        this.addEventListener('message', run, false);
    </script>

    <script>
        var base_url = window.location.href.replace(/\\/g,'/').replace(/\/[^\/]*$/, '');
        var array = ['var base_url = "' + base_url + '";' + $('#worker_1').html()];
        var blob = new Blob(array, {type: "text/javascript"});

        $('button').click(function() {
            var url = window.URL.createObjectURL(blob);
            console.log(url);
            var worker = new Worker(url);
            worker.addEventListener('message', function(event) {
                $('#output').html(event.data.answer);
            }, false);
            worker.postMessage({
                name: 'Steve'
            });
        });
    </script>
</body>

With the library worker_lib2.js containing the hello function.

function hello(msg) {
    return 'Hello... ' + msg;
}
jlguenego
  • 1,192
  • 15
  • 23