Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a correct way to 'yield' in the cooperative threading sense in javascript?

I'm writing a ubiquity plugin the long function callback for an ajax query is blocking up the GUI Thread causing firefox to lock up.

The obvious solution seem to be to use some sort of deferred execution of (i.e we want to periodically add the carry out doing this query function to the end of the event queue and then allow other commands to be carried out.

The only way I can think of doing this is to use settimeout with a timeout of zero... is this is guaranteed to work, or is there a better way of doing this.

like image 942
user47741 Avatar asked Sep 20 '09 21:09

user47741


2 Answers

Using setTimeout with a very small timeout (0 or very nearly zero if you're feeling paranoid) is the only way to do this in a browser context. It works very well and is very reliable, but be sure to yield often enough but not too often, as it does take a while to come back to you ("a while" in a computer sense, of course; it's almost instantaneous [modulo other things you may be doing] in human terms).

like image 76
T.J. Crowder Avatar answered Oct 31 '22 05:10

T.J. Crowder


Make sure you are using an asynchronous request as a synchronous request blocks the browser (which would explain the GUI lock-up).

If this is not your problem, I think you want something like this task queue.

var queue = [];

queue.push(someTaskFunction);
queue.push(anotherTaskFunction);
// ...

var runQueue = (function () {
    var len = queue.length, task = 0;
    for (; task < len; task++) {
        yield queue[task]();
    }
}());

Call runQueue.next() to execute the next task. Wrap it in a try..catch statement as such:

try {
    runQueue.next();
} catch (e if (e instanceof StopIteration)) {}
like image 3
Eli Grey Avatar answered Oct 31 '22 04:10

Eli Grey