Ashwin
Ashwin

Reputation: 1960

setTimeout with The Revealing Module Pattern

In Revealing module pattern of JavaScript how to use setTimeout function?

Here is the example.

HTML: <div id="container1"></div>

JavaScript:

var classA = (function() {
    var i = 0;
    var names = ["a", "b", "c", "d", "e", "f"];
    var callTest = function() {
        for (var n in names) {
            window.setTimeout(function() {
                callTest2(names[n]);
            }, 1000);
        }
    };

    var callTest2 = function(pName) {
        $("#container1").append("In callTest   " + i+++" " + pName + "<br>");
        window.setTimeout(function() {
            callTest2(pName)
        }, 10000)
    };

    return {
        testTheTest: function() {
            callTest();
        }
    }
})();

classA.testTheTest();

Framework: jQuery 1.5.2

When I execute the output is:

In callTest 0 f
In callTest 1 f
In callTest 2 f
In callTest 3 f
In callTest 4 f
In callTest 5 f

Instead of:

In callTest 0 a
In callTest 1 b
In callTest 2 c
In callTest 3 d
In callTest 4 e
In callTest 5 f

What am I missing? Where am I doing wrong?

Upvotes: 4

Views: 874

Answers (3)

Fedor Skrynnikov
Fedor Skrynnikov

Reputation: 5609

cause the function insight setTimeout is calling not in that place, but after 1sec. And when it is called the n is equal to the last index. You have to make n global and increment each time the function is called

var classA = (function() {
    var i = 0;
    var names = ["a", "b", "c", "d", "e", "f"];
    var n = 0;
    var callTest = function() {
        for (var i in names) {
            window.setTimeout(function() {
                callTest2(names[n]);
                n++;
            }, 1000);
        }
    };

    var callTest2 = function(pName) {
        $("#container1").append("In callTest   " + i+++" " + pName + "<br>");
        window.setTimeout(function() {
            callTest2(pName)
        }, 10000)
    };

    return {
        testTheTest: function() {
            callTest();
        }
    }
})();

classA.testTheTest();

Upvotes: 2

Umesh Patil
Umesh Patil

Reputation: 10695

   for (var n in names) {
            window.setTimeout(function() {                
                callTest2(names[n]);
            }, 1000);
        }

Code above is equivalent to below code.

    callTest2("f");
    callTest2("f");
    callTest2("f");
    callTest2("f");
    callTest2("f");
    callTest2("f");

Why..? Reason is function callTest2() is called after completion of one second, but before that whole names[] array is already iterated and "f" last character is passed to function callTest2.

For loop is iternated at very little fraction of micro-second. i.e. names[] array will be iterated in very little time. At the end last character remains as "f" i.e. names[n].

Upvotes: 1

jabclab
jabclab

Reputation: 15062

I've made a few slight modifications to your code which means it now works as you wish it to:

var classA = (function() {
    var i = 0,
        names = ["a", "b", "c", "d", "e", "f"],
        namesLength = names.length,
        callTest = function() {
            window.setTimeout(function() {
                callTest2(0);
            }, 1000);
        },
        callTest2 = function(pIndex) {
            if (pIndex < namesLength) {
                var name = names[pIndex++];
                $("#container1").append("In callTest   " + i+++" " + name + "<br>");
                window.setTimeout(function() {
                    callTest2(pIndex);
                }, 1000);
            }
        };

    return {
        testTheTest: function() {
            callTest();
        }
    }
})();

classA.testTheTest();

Here's a working example.

Upvotes: 2

Related Questions