views:

226

answers:

5

Does anyone know how I can write a Javacript function which returns true if the browser's Javascript engine has been idle for a certain amount of time?

I am happy to use mootools / jQuery etc if easier, with a slight preference for mootools.

EDIT:

My actual problem: I'm making a call to a 3rd party's API. The call returns immediately but the actual work it does to the DOM goes on for some time (> 10 seconds in many cases). I want some code of mine to run as soon as the DOM work is complete. I know nothing about the internals of the API function I'm calling, so I was looking for a generic way of determining whether the function had finished.

A: 

There are two fact you can exploit to measure the idleness of the javascript/flash thread.

  1. Javascript has timing sources (setTimeout, setInterval) that tick only when javascript is idle. Thus the less idle the thread, the slower the timer.

    "JavaScript can only ever execute one piece of code at a time (due to its single-threaded nature) each of these blocks of code are "blocking" the progress of other asynchronous events. This means that when an asynchronous event occurs (like a mouse click, a timer firing, or an XMLHttpRequest completing) it gets queued up to be executed later." How JavaScript Timers Work

  2. Javascript has an external timing source which ticks regardless of idleness. The class instance Date() is based on an external clock, you can get millisecond timing using getTime():

    var timeSinceDisco = (new Date).getTime();

eJohn has some interesting tests using getTime() for benchmarking.

We use the difference between the external timer Date.getTime(), and the internal time setTimeout to calculate the degree of idleness of the javascript thread. Of course this isn't going to work as well on sexy new javascript engines like V8 or tracemonkey as they use more than one thread. It should work for most browsers currently out there.

Lessons from Gmail: Using Timers Effectively

e5
Are you sure this isn't implementation-dependent?
Cide
i agree with Cide, but otherwise a clever approach
larson4
@Cide In my experience setTimeout works the same across all but the multi-threaded js engines. I agree though that is it likely there is some pretty tricky different behavior between browsers.
e5
A: 

I am 99.4% certain there is no such function, however, I wish there was because I really need it.

Of course, you could build your own solution here (a function that you call at the beginning of every entry point function), depending on the details could be low overhead.

var Tracker={ 
 last: new Date().geTime(),
 activity:function() { this.last=new Date().geTime(); },
 idle:function() { return new Date().geTime()-this.last; }
 }


...

var clickedSomething=function() {
 Tracker.activity();
 ...real code..
 }
larson4
+3  A: 

If you call such a function, won't that reset any idle time counter, assuming one exists?

If you could outline the problem you are trying to solve it may be that we can give you a hand. I can think of ways that I would approach solving the problem of "how long has it been since this function ran" or "how long since the last event on the page" or "do something if the user has been on this page for X seconds", but I don't there is any good way of doing "do this only when nothing has happened for X seconds".

Update

Based on your update, I'd look for a callback mechanism in the API (could you share what it is?) that would allow you to schedule some work for after the API is complete. If that doesn't work, you could try adding something like:

setTimeout( function() { myCallbackMethod(); }, 0 );

This will schedule your callback to start once the current execution is completed. It depends on the javascript engine being single-threaded, but I've seen it used to good effect.

tvanfosson
I've added to my question.
jjujuma
A: 

You could call a function to check mouse X and Y position each timer interval, and compare them to last saved X and Y position, if they are the same, so it's idle.

MooTools Sample

Ahmed
Same comment as to @Kip: This is "is the user idle?" not "is the javascript engine idle?"
tvanfosson
A: 

I think this one can be useful

https://sourceforge.net/projects/idleness/

phil