I need to call the javascript function dynamically after some delay, The function display_1, 2, ... n will be dynamically constructed. My script looks like this, but the function never gets triggered if I use the following code, but if I hardcode the function it just seems to be fine.
function display_1() {
alert(1);
}
function display_2() {
alert(2);
}
function display() {
var prefix = 'display_';
for(var i = 1; i < 3; i++) {
setTimeout(prefix.concat(i), 1000);
}
window.onload = display();
Instead of going via a string, you may as well group the functions into an array:
function display_1() {...}
function display_2() { ... }
var functions = [ display_1, display_2 ];
function display() {
for( var i = 0; i != functions.length; ++i ) {
setTimeout( functions[i], 1000 );
}
}
If you want to go further, you may even leave out the explicit function names:
var functions = [
function() { /*the function_1 implementation*/
},
function() { /*the function_2 implementation*/
}
];
you have to add the parenthesis so that the function is called:
setTimeout(prefix.concat(i)+"()", 1000);
or simply:
setTimeout(prefix + i + "()", 1000);
Besides of that please note that both functions are called pratically at the same time, because the timers started with ´setTimeout()` start at the same time.
Depending on what you're trying to do you might have a look at setInterval() or start the second timeout at the end of the display_1() function.
It should be
function display_1() {
alert(1);
}
function display_2() {
alert(2);
}
function display() {
var prefix = 'display_';
for(var i = 1; i < 3; i++) {
setTimeout(prefix.concat(i)+'()', 1000);
}
}
window.onload = display;
the string passed to setTimeout should call the function
onload should be set to a function, not its return value
setInterval('load_testimonial()',5000);//first parameter is your function or what ever the code u want to execute, and second is time in millisecond..
this will help you to execute your function for every given time.
If you really want a 1000ms delay between executing the functions, you could do something like this:
window.onload = function() {
var n = 0;
var functions = [
function() {
alert(1);
setTimeout(functions[n++], 1000);
},
function() {
alert(2);
setTimeout(functions[n++], 1000);
},
function() {
alert(3);
}
];
setTimeout(functions[n++], 1000);
};
(rewrite it in a less-repetitive nature if needed)
Related
I have a function that is used to send messages and that is called multiple times in a sec.
But I want to call that function once a sec and delay other calls of that function with another 1-second of the previous call.
So that only that function run in the background and called once in a second, no matters how many times it is called it will delay each call to one second ahead.
For example:
function foo(a) {
console.log(a)
}
foo('one');
foo('two');
foo('three');
in the above example, foo is called three times within a sec but I want to have it called like after the 1 second it should return "one" after 2 seconds it should return 'second' and so on and it should be asynchronous.
How can I do this?
The technology I am using is Javascript.
Thanks
Well this is the first thing I came up with - perhaps it's crude.
var queuedUpCalls = [];
var currentlyProcessingCall = false;
function foo(a) {
if (currentlyProcessingCall) {
queuedUpCalls.push(a);
return;
}
currentlyProcessingCall = true;
setTimeout(function(){
console.log(a);
currentlyProcessingCall = false;
if (queuedUpCalls.length) {
var nextCallArg = queuedUpCalls.shift();
foo(nextCallArg);
}
},1000);
}
foo('one');
foo('two');
foo('three');
For each call, if you're not currently processing a call, just call setTimeout with a delay of 1000ms. If you are processing a call, save off the argument, and when the setTimeout that you kicked off finishes, process it.
Somewhat improved answer using setInterval:
var queuedUpCalls = [];
var timerId;
function foo(a) {
queuedUpCalls.push(a);
if (timerId) {
return;
}
timerId = setInterval(function(){
if (!queuedUpCalls.length) {
clearInterval(timerId);
timerId = null;
return;
}
var nextCallArg = queuedUpCalls.shift();
console.log(nextCallArg);
}, 1000);
}
foo('one');
foo('two');
foo('three');
Here is a simple queue system, it basically just pushes the functions onto an array, and then splice's them off every second.
const queue = [];
setInterval(function () {
if (!queue.length) return;
const f = queue[0];
queue.splice(0, 1);
f();
}, 1000);
function foo(a) {
queue.push(function () {
console.log(a)
});
}
foo('one');
foo('two');
foo('three');
you could use this to run the main code first and then run some more code a little later.
function firstfunction() {
alert('I am ran first');
setTimeout(function(){ alert('I am ran 3 seconds later') }, 3000);
}
<button onclick="firstfunction();">click me</button>
function foo(a)
{
if (typeof foo.last == 'undefined')
foo.last = Date.now();
var now = Date.now();
if (now - 1000 > foo.time)
foo.last = now;
setTimeout(function()
{
console.log(a);
}, (foo.last += 1000) - now);
}
This will queue each console.log call with intervals of 1 second, the first call will also be delayed by 1 second.
You could do this:
function foo() {
console.log(“ran”);
}
setInterval(foo, 1000);
In the last line, writing foo() without parenthesis is intentional. The line doesn’t work if you add parentheses.
I'm trying to make simple autotype with Javascript. My problem is the autotype is cannot run sequentially if i call it from view (.cshtml).
My cshtml like this:
<script type="text/javascript" src="#Url.Content("/Scripts/autotype.js")"></script>
#foreach (var temp in #Model)
{
<script>
auto_type("ABCDEFG", 0)
</script>
}
<div id="divauto"></div>
and it's autotype.js :
function auto_type(wrt, i) {
wrt = wrt.split('');
var delay = 100;
while (i < wrt.length) {
setTimeout(function () {
$('#divauto').append(wrt.shift())
}, delay * i)
i++;
}
}
From these codes, the output will be like "AAABBBCCCDDDEEEFFFGGG" but i need the output like: "ABCDEFGABCDEFGABCDEFG"
You can do this with jQuery deferreds. In this case I had to use two recursive functions since you need flow control for both the iteration through the viewItems list as well as for kicking off setInterval() to update #divAuto for each character.
As an example of how promises are used here to add control, in autoType() you get a promise returned from the new autoTypeUtil(). When the promise is resolved within autoTypeUtil() you call autoType() again with the remaining list. This gives you flow control for the input items while still running asynchronously.
You may check out the fiddle for a working example.
function timeString(arr, timeFactor, deferred) {
if (arr.length === 0) { deferred.resolve(); }
var ch = arr.shift();
var deferredInternal = new $.Deferred();
var promise = deferredInternal.promise();
var delay = 100;
setTimeout(function () {
$('#divauto').append(ch);
deferredInternal.resolve("done");
}, delay * timeFactor)
promise.done(function() {
timeString(arr, timeFactor, deferred);
});
}
function autoTypeUtil(inputString, timeFactor) {
var deferredTimeString = new $.Deferred();
var deferredInternal = new $.Deferred();
var promiseTimeString = deferredTimeString.promise();
inputString = inputString.split('');
timeString(inputString, timeFactor, deferredTimeString);
promiseTimeString.then(function() {
deferredInternal.resolve()
});
return deferredInternal.promise();
}
function autoType(arr, timeFactor) {
if (arr.length === 0) { return; }
var promise = autoTypeUtil(arr.shift(), timeFactor);
promise.done(function() {
autoType(arr, timeFactor);
});
}
var viewItems = ["I", "love", "jQuery", "promises"];
autoType(viewItems, 1);
I think what you are looking for is a typewriter, or teletype effect, where the text is written out like a typewriter?
In that case, check out this SO question, as it looks like it will provide what you need.
Typewriter Effect with jQuery
The issue is that i is getting set to 7 at the end of your loop, which occurs before the first instance of it being called. Try something like this:
function auto_type(wrt) {
wrt = wrt.split('');
if (wrt.length > 0) {
var delay = 100;
type_loop(wrt, delay);
}
}
function type_loop(wrt, delay) {
var myTimeout = setTimeout(function () {
clearTimeout(myTimeout);
$('#divauto').text($('#divauto').text() + wrt.shift());
if (wrt.length > 0) {
type_loop(wrt, delay);
}
}, delay);
}
$(document).ready(function() {
auto_type("ABCDEFG", 0);
});
This method is called tail recursion in case you're curious.
I'm trying to apply what I learned about callback functions in this post I made to extend to 3 functions, but am having some trouble getting things working. Can someone please help me understand how I can get these three functions to fire in sequence?
var yourCallback = function(args, second) {
var t = setTimeout(function() {
$('body').append(args);
}, 800);
second('3-');
}
var yourSecondCallback = function(args) {
var t = setTimeout(function() {
$('body').append(args);
}, 800);
}
function function1(args, callback, yourSecondCallback) {
$('body').append(args);
if (callback) {
callback('2-');
}
}
function1('1-' , yourCallback);
http://jsfiddle.net/loren_hibbard/WfKx2/3/
Thank you very much!
You need to nest the callbacks to get them to call in order.
var yourCallback = function(args, second) {
var t = setTimeout(function() {
$('body').append(args);
second('3-');
}, 800);
}
var yourSecondCallback = function(args) {
var t = setTimeout(function() {
$('body').append(args);
}, 800);
}
function function1(args, callback) {
$('body').append(args);
if (callback) {
callback('2-', yourSecondCallback);
}
}
function1('1-' , yourCallback);
Here's your altered fiddle
Your function names confuse me, so I'm just going to make some up to demonstrate a simple approach:
function1('-1', function(){
secondCallback(...);
thirdCallback(...);
...
});
Any reason a simple approach like that won't work for you?
Not sure exactly what you are trying to do here, but when you do this in function1:
callback('2-');
You are calling this method:
var yourCallback = function(args, second)
But you are not providing a value for second, so you get an error.
If your first argument and only is going to be an input for all the callbacks then this code can be used for unlimited arguments
var yourCallback = function(args, second) {
var t = setTimeout(function() {
$('body').append(args + ' first function');
}, 800);
}
var yourSecondCallback = function(args) {
var t = setTimeout(function() {
$('body').append(args + ' second function');
}, 800);
}
function function1(args) {
var callbacks = arguments.length - 1;
for (i = 1; i < arguments.length; i++) {
if (typeof(arguments[i] == 'function')) {
arguments[i](arguments[0]);
}
}
}
function1('1-', yourCallback, yourSecondCallback);
Fiddle - http://jsfiddle.net/8squF/
I have a function, mainMethod, that is calling three callback functions.
mainFunction the first callback function(one) will be called and the first parameter will be passed into it.
one will pass the second parameter into the second callback function (two).
two will pass the third parameter into the last callback function (three).
three will just log the last parameter that was passed into it.
function mainFunction(callback1, callback2, callback3){
var first_parameter = "ONE"
callback1(first_parameter);
}
function one(a){
console.log("one: " + a);
var second_parameter = "TWO"
two(second_parameter);
}
function two(b){
console.log("two: " + b);
var third_parameter = "THREE";
three(third_parameter);
}
function three(c){
console.log("three: " + c);
}
mainFunction(one, two, three);
I have assigned 5000 ms to Settimeout but it is executing before assigned time interval.Can any body explain why it is happening.
<script type="text/javascript">
var getcallback = {
closure: function (callback, functionparam) {
return callback.call(functionparam);
}
}
var cleartimeout;
var startSlideShow = {
timerid: 5000,
startAnimation: function () {
cleartimeout = setTimeout(getcallback.closure(function () {
alert("this is a basic example of chaining methods");
this.startAnimation();
},this), this.timerid);
},
stopAnimation:function(){
}
}
startSlideShow.startAnimation();
</script>
Because getcallback.closure() is executing the function right away, you are not storing a reference to a function to call at a later time.
As soon as you call startAnimation, you're calling getcallback.closure, which immediately calls the callback function. To use setTimeout correctly, you need to either have closure return a function, or not use such a strange thing, and instead just use an anonymous function.
Something along the lines of:
var getcallback = {
closure: function (callback, functionparam) {
return function() {
callback.call(functionparam);
};
}
}
...
Or, to be cleaner, just:
var cleartimeout;
var startSlideShow = {
timerid: 5000,
startAnimation: function () {
cleartimeout = setTimeout(function () {
alert("this is a basic example of chaining methods");
this.startAnimation();
}, this.timerid);
},
stopAnimation:function(){
}
}
startSlideShow.startAnimation();
I have a banner rotator and I wanted to use objects instead of functions so I could make the code more efficient. Anyway I can't seem to get setInterval to work. I think it's got something to do with the object reference. Can anybody explain this? Here's what I've got so far:
window.addEvent('domready', function() {
function set_banner(divid, array)
{
var banner = $(divid);
banner.set('html', '<img src="" alt=""/>');
var banner_link = $(divid).getElement('a');
var banner_image = $(divid).getElement('img');
var delay = 0;
for (var keys in banner1array) {
var callback = (function(key) { return function() {
banner.setStyle('opacity', 0);
var object = array[key];
for (var property in object) {
if (property == 'href') {
var href = object[property];
}
if (property == 'src') {
var src = object[property];
}
}
if (!banner.getStyle('opacity')) {
banner.set('tween', {duration:1000});
banner_link.setProperty('href', href);
banner_image.setProperty('src', src);
banner.tween('opacity', 1);
}
}; })(keys);
setTimeout(callback, delay);
delay += 21000;
}
}
var banner1 = set_banner('banner1', banner1array);
setInterval(function() {set_banner('banner1', banner1array);}, 84000);
var banner2 = set_banner('banner2', banner2array);
setInterval(function() {set_banner('banner2', banner2array);}, 84000);
});
A couple of simple mistake:
var banner1 = new set_banner('banner1');
^ ---------- creates a new object and uses set_banner as the constructor
your code already gets called here
and you get a new object back, which in this case has NO use
....
setInterval(banner1(), 42000);
^----------------- The parenthesis EXECUTE the function
the RETURN VALUE is then passed to setInterval
BUT... banner1() is NOT a function, so this fails
What you want to do in case that you want to call set_banner after 42 seconds AND pass a parameter is to use an anonymous function which then calls set_banner.
setInterval(function() { // pass an anonymous function, this gets executed after 42 seconds...
set_banner('banner1'); // ...and then calls set_banner from within itself
}, 42000);
Something else to consider: http://zetafleet.com/blog/why-i-consider-setinterval-harmful.
(tl:dr Instead of setInterval, use setTimeout.) While I'm not sure that his arguments apply here, it seems like a good thing to get in the habit of avoiding.
function defer_banner(div, bannerArray, delay) {
setTimeout(function() {
setBanner(div, bannerArray);
defer_banner(div, bannerArray, delay);
}, delay);
});