Can JavaScript setInterval JavaScript block execution?

Could setInterval lead to other scripts in the page lock?

I am working on a project to convert a Gmail related bookmarklet to a Google Chrome extension. Bookmarks use the gmail greasemonkey API to interact with the gmail page. The JavaScript API object is one of the last parts of the Gmail page to load and is loaded into the page via XMLHttpRequest. Since I need access to this object, and JavaScript global variables are hidden from content scripts, I insert a script into the gmail page that polls for the definition of the variable and then accesses it. I am doing a poll using the setInterval function. This works about 80% of the time. The rest of the time, the polling function continues polling until it reaches the limit I set, and the greasemonkey API object is never defined on the page.

Injected sample script:

    var attemptCount = 0;

    var attemptLoad = function(callback) {

        if (typeof(gmonkey) != "undefined"){
            clearInterval(intervalId);  // unregister this function for interval execution.
            gmonkey.load('1.0', function (gmail) {
                self.gmail = gmail;
                if (callback) { callback(); }
            });
        }
        else {
            attemptCount ++;  
            console.log("Gmonkey not yet loaded: " + attemptCount );
            if (attemptCount > 30) {
                console.log("Could not fing Gmonkey in the gmail page after thirty seconds.  Aborting");
                clearInterval(intervalId);  // unregister this function for interval execution.
            };
        }
    };

    var intervalId = setInterval(function(){attemptLoad(callback);}, 1000);

      

+1


source to share


2 answers


Javascript is single threaded (except for web workers, which we are not talking about here). This means that as long as the normal javascript thread is running, your timer setInterval()

will not run until the normal javascript thread is executed.

Likewise, if your handler setInterval()

is executed, no other javascript event handlers are triggered until your handler setInterval()

completes the current call.

So, until your handler setInterval()

gets stuck and starts forever, it won't block other things eventually. This may delay them a bit, but they will still work as soon as the current thread ends setInterval()

.

Internally, the javascript engine uses a queue. When something wants to be triggered (like an event handler or callback setInterval()

) and something is already running, it inserts the event into the queue. When the current javascript thread finishes executing, the JS engine checks the event queue and, if there is anything there, it fetches the oldest event and calls its event handler.



Here are a few other links on how the Javascript event system works:

How does JavaScript handle AJAX responses in the background?

Are Javascript method calls thread safe or synchronized?

Do I need to worry about race conditions with asynchronous Javascript?

+10


source


setInterval and setTimeout are "polite" in that they don't fire when you think they will - they fire whenever the stream is clear, after a point you specify.

So the process of scheduling something won't stop something else from starting - it just sets itself to run at the end of the current queue, or at the end of a specified time (whichever is greater).

Two important caveats:

The first is that setTimeout / setInterval have browser restrictions. They are often around 15ms. So if you ask for something every 1ms, the browser actually plans to split them on each browser_min_ms (not a valid variable).

Second, with setInterval, if the script in the callback takes longer than the interval, you might run into a trip where the browser will maintain the order of the intervals.



function doExpensiveOperation () {
    var i = 0, l = 20000000;
    for (; i < l; i++) {
        doDOMStuffTheWrongWay(i);
    }
}


setInterval(doExpensiveOperation, 10);

      

BadTimes + = 1;

But for your code specifically, there is nothing wrong with what you are doing. As I said, setInterval will not cancel anything else from happening, it will just add itself to the next available slot.

I would probably recommend using setTimeout for general-purpose stuff, but you still do good tab recordings and keep them at a distance.

It is possible that something is happening elsewhere in the code - either in google delivery or in your collection.

+4


source







All Articles