Reputation: 1960
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
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
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
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