2

1) Can someone illustrate how setTimeout works in terms of execution threads.

Consider:

function foo() { alert('foo'); }
function bar() { alert('bar'); }  
setTimeout(foo,1000);
bar();

or

function foo() { alert('foo'); setTimeout(foo,1000); }
function bar() { alert('bar'); }  
setTimeout(foo,1000);
bar();

or

function foo() { alert('foo'); setTimeout(foo,1000); }
function bar() { /* an execution that runs with unknown time */ }  
setTimeout(foo,1000);
bar();

or

function foo() { alert('foo'); setTimeout(foo,1000); }
function bar() { /* some ajax call that reply with unknown time */ }  
setTimeout(foo,1000);
bar();

or

function foo() { alert('foo'); setTimeout(foo,1000); }
function bar() { alert('foo'); setTimeout(bar,1000); }  
setTimeout(foo,1000);
setTimeout(bar,1000);

2) Can someone explain how why "this" object doesn't work in setTimeout and what we can do to get around that problem?

4
  • 4
    All of those calls to setTimeout will do nothing at all. You're passing in "foo" as a string, which will be interpreted as meaning you want a function whose body looks like the string contents. Commented Dec 13, 2012 at 23:04
  • 1
    Take a look at the MDN: developer.mozilla.org/en-US/docs/DOM/… Commented Dec 13, 2012 at 23:04
  • The context of setTimeout is window, to use this from the function cache it before. Commented Dec 13, 2012 at 23:05
  • 1) You are alerted bar, then foo. 2) You are alerted bar, then foo every second. However setInterval(foo, 100) would do the same thing better. 3) bar fully executes, and after 10 seconds foo executes. A timer pushes something to the bottom of the priority queue. 4) Again, foo will wait until bar has finished execution. Commented Dec 13, 2012 at 23:05

2 Answers 2

9

Do read the article suggested by @DaveAnderson.

As to the other stuff, the setTimeout/setInterval has two forms:

setTimeout(arg, timeout)

If arg is a string, then it's treated as the source code to be executed. This is as bad as eval(). Avoid it.

If arg is a function, then it's executed in the global context:

var Test = function () {
    this.x = 1;
    setTimeout(function () {
        console.log('x: ' + this.x);
    }, 10);
};

var t = new Test();

Prints x: undefined.

So what you wanted to do is:

function foo() { alert('foo'); }
setTimeout('foo()', 1000);

or better:

setTimeout(foo, 1000);

To fix the context of the function, use the bind method:

var Test = function () {
    this.x = 1;
    var f = function () {
        console.log('x: ' + this.x);
    };
    setTimeout(f.bind(this), 10);         // use this as the context
};

var t = new Test();

or do it manually:

var Test = function () {
    this.x = 1;
    var that = this;
    setTimeout(function () {
        console.log('x: ' + that.x);     // closure: closing over that
    }, 10);
};

var t = new Test();
Sign up to request clarification or add additional context in comments.

2 Comments

The article I suggested was John Resig's How JavaScript Timers Work but the answer was deleted by a moderator, hopefully providing this comment is appropriate instead.
the last approach is quite interesting
0

As far as I could recall:

var me = this;
me.f();

(this may change its meaning in another context).

1 Comment

Conceptually yes, but please fill in the function expression and the call to setTimeout.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.