setTimeout doesn't work as expected because it will execute the codes below subsequently without waiting for the delay to run the first argument of 'setTimeout'
(function() {
var a = ['#bird','#flower','#cat'];
var totalno = settings.imageArray.length;
function rotateImages(start) {
var nextImage = start + 1;
if(nextImage % totalno == 0){
nextImage=0;
}
//do animate here
$(settings.imageArray).fadeOut();
window.setTimeout(function() {
rotateImages(++start % totalno);
}, settings.imageArray[start].delay);
}
rotateImages(0);
})();
Is there a way to write it so that it doesnt fade out right away for the first image?
a simplified version would be :
(function() {
var a = ['#bird','#flower','#cat'];
function rotateImages(start) {
//do something here
window.setTimeout(function() {
rotateImages(++start % a.length;);
}, 1000);
}
rotateImages(0);
})();
it will execute the codes below
subsequently without waiting for the
delay to run the first argument of
'setTimeout'
It looks like you're starting the first rotate directly. Instead of:
rotateImages(0);
Try to start the first rotate with a delay, like:
window.setTimeout(function() {
rotateImages(0);
}, settings.imageArray[0].delay);
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 working on some code that'd I'd like to have each loop run every 60 seconds, but currently each loop runs immediately. The purpose of the code it to see if a form has changed, and if it has save the form. Do I have setInterval setup incorrectly?
function saveHelper(formId) {
for(var i = 0; i < 4; i++) {
save(formId);
}
}
function save(formId) {
console.log('might save');
var changed = formChanges(formId);
var intId = setInterval(stall, 60000);
if(changed.length > 0) {
console.log('would save');
//document.getElementById(formId).submit();
}
clearInterval(intId);
}
function stall() {
return true;
}
You are treating interval as some sort of synchronous sleep method, which is not the case. The change code should be inside of the setInterval, it should not live after the interval.
var intId = setInterval(function () {
if(changed.length > 0) {
console.log('would save');
//document.getElementById(formId).submit();
}
}, 60000);
setInterval doesn't pause your code, it just schedules some code to be run some time in the future. For example, when you do this:
var intId = setInterval(stall, 60000);
That says "every 60000 milliseconds, run the function stall". As soon as this line of code completes, it will immediately run your next line of code, do the saving, then clear the interval. Clearing the interval cancels it, so now nothing will happen in 60000 milliseconds.
Instead, you'll want to do something like this:
function saveHelper(formId) {
let count = 0;
const intId = setInterval(function () {
if(changed.length > 0) {
console.log('would save');
//document.getElementById(formId).submit();
}
count++;
if (count === 4) {
clearInterval(intId);
}
}, 60000);
}
Every 60000 milliseconds, the inner function will run, and do the saving. After saving, it checks how many times we've done this, and once it reaches 4, it clears the interval to stop it from happening any more.
I want to execute a block of code every two seconds—to accomplish this, I thought the easiest way would be to retrieve the current system time as so:
if ((Date().getSeconds()) % 2 == 0) {
alert("hello"); //I want to add code here!
}
However, my alert is not printing to the screen every two seconds. How can this be properly implemented?
In order to run a block of code every x seconds, you can use setInterval.
Here's an example:
setInterval(function(){
alert("Hello");
}, x000); // x * 1000 (in milliseconds)
Here's a working snippet:
setInterval(function() {
console.log("Hello");
}, 2000);
You can use setInterval(). This will loop every 2 seconds.
setInterval(function() {
//something juicy
}, 2000);
Try using the setInterval() method
setInterval(function () {console.log('hello'); }, 2000)
This should work for you.
setInterval(function() {
//do your stuff
}, 2000)
However, to answer why your code is not working, because it is not in a loop.
runInterval(runYourCodeHere, 2);
function runInterval(callback, interval) {
var cached = new Array(60);
while (true) {
var sec = new Date().getSeconds();
if (sec === 0 && cached[0]) {
cached = new Array(60);
}
if (!cached[sec] && sec % interval === 0) {
cached[sec] = true;
callback();
}
}
}
function runYourCodeHere() {
console.log('test');
}
I want a counter which reset in specific interval of time. I wrote this code. When I refresh the page it is executing perfectly. But as time passes the timer goes really fast, skipping seconds. Any idea why this is happening.
function countdown_new() {
window.setInterval(function () {
var timeCounter = $("b[id=show-time]").html();
var updateTime = eval(timeCounter) - eval(1);
$("b[id=show-time]").html(updateTime);
if (updateTime == 0) {
//window.location = ("ajax_chart.php");
$("b[id=show-time]").html(5);
clearInterval(countdown_new());
// countdown_new();
//my_ajax();
}
}, 1000);
}
window.setInterval(function () {
countdown_new();
}, 5000)
HTML
Coundown in 5 seconds
The issue is because you are not clearing the previous timer before starting a new one, so you start a new one for each iteration. To clear the timer you should save a reference to it, and pass that to clearInterval, not a function reference.
Also, note that your pattern of using multiple intervals for different operations can lead to overlap (where two intervals are acting at the same time and cause odd behaviour). Instead, use setTimeout for the initial 5 second delay and then chain further calls to stop this overlap.
Try this:
var timer;
function countdown_new() {
timer = setInterval(function () {
var $showTime = $("#show-time")
var updateTime = parseInt($showTime.text(), 10) - 1;
$showTime.html(updateTime);
if (updateTime == 0) {
$showTime.html('5');
clearInterval(timer);
setTimeout(countdown_new, 5000);
}
}, 1000);
}
setTimeout(countdown_new, 5000);
Example fiddle
Note that you should use the # selector to select an element by its id attribute, and you should never use eval - especially not for type coercion. To convert a value to an integer use parseInt().
You are calling window.setInterval(), which schedules a function call to countdown_new() ever 5 seconds without stop.
Compounding the problem, you are calling countdown_new() again inside your clear interval.
You need to call setInterval just once to continuously execute a function every 5 seconds.
If you want to cancel an interval timer, you need do to this:
var intervalObj = setInterval(function() { ... }, 5000);
clearInterval(intervalObj);
Yes clearinterval does the trick.
function countdown_new(){
t = window.setInterval(function() {
var timeCounter = $("b[id=show-time]").html();
var updateTime = eval(timeCounter)- eval(1);
$("b[id=show-time]").html(updateTime);
if(updateTime == 0){
//window.location = ("ajax_chart.php");
$("b[id=show-time]").html(5);
clearInterval(t);
// countdown_new();
my_ajax();
}
}, 1000);
}
function ShowColoursScreen() {
setSquaresList()
$("#ModeOne").hide();
$("#ModeTwo").show();
setTimeout(function () {
$("#ModeOne").show();
$("#ModeTwo").hide();
setTimeout(function () {
ShowColoursScreen();
}, 1500);
}, 15000);
}
This is very very weird, Im wanting to rotated between two divs every 15 seconds (i dont want to use js intervals). However after the first fifteen seconds ShowColoursScreen(); runs without waiting the second 15 seconds (if that makes sense). Its like the timeout gets ignored, any ideas?
Your code is correct. However, the inner timeout just waits for 1.5 seconds as you forgot a zero. Simply replace the 1500 with 15000.
You can also simplify the call a bit - as you do not have any arguments there is no need for the anonymous function: setTimeout(ShowColoursScreen, 15000);
function ShowColoursScreen($elements) {
if(!$elements instanceof jQuery) {
$elements = $($elements);
}
var current = 0;
// What does this function do?
setSquaresList();
function showCurrent () {
var $currentElement = $($elements[current]);
$elements.not($currentElement).hide();
$currentElement.show();
(current++) % $elements.length;
setTimeout(showCurrent, 15000);
}
showCurrent();
return $elements;
}
ShowColoursScreen('#ModeOne, #ModeTwo')