My setTimeout doesn't respect the delay - javascript

I want to repeat a function every 10s with setTimeout. My function is:
dateInLive = function() {
crono = function(){
setTimeout(function() {
$('.datePoste').each(function(){
$(this).load('in_live.php','in_live='+$(this).attr('id'))
});
crono();
}
,10000);
}
crono();
}
But, it's really random; sometimes it's repeating after 15s, sometimes after 3s, sometimes after 6s.

Recall crono() only when all the ajax requests are completed :
function crono(){
setTimeout(function() {
var arr = [];
$('.datePoste').each(function(){
var self = this;
xhr = $.get('in_live.php', {in_live : this.id}, function(data) {
$(self).html( $.parseHTML(data) );
});
arr.push(xhr);
});
$.when.apply($, arr).done(crono);
}, 10000);
}

You're using setTimeout to run a repeated event.
This is correct (others have recommended setInterval instead, but there are issues with this).
However you aren't setting the timeout on the subsequent calls -- you're just calling the crono() function directly, so after the initial timeout delay, it will then just start calling itself immediately over and over and over forever (until it exhausts the stack space).
What you need to do is call setTimeout() each time you call the function. Recode it something like this:
dateInLive = function() {
crono = function(){
$('.datePoste').each(function(){
$(this).load('in_live.php','in_live='+$(this).attr('id'))
});
setTimeout(crono,10000);
}
setTimeout(crono,10000);
}

In this situation, i would use deferred objects.
function crono(){
setTimeout(function() {
var defArr = [];
$('.datePoste').each(function(i,el){
var deferred = $.Deferred();
defArr.push(deferred.promise());
$(this).load('in_live.php','in_live='+$(this).attr('id'), function() {
deferred.resolve();
});
});
$.when.apply($,defArr).done(crono);
}, 10000);
}
Doing it this way will request all sections, then when all sections are received, wait 10 seconds and request them again, avoiding the request from piling up in a slow network situation.

you are doing something before creating the new timeout, which means there is bound to be "some" delay.
have a look at the setInterval() function.

You just have the crono() function in the wrong place.
dateInLive = function() {
crono = function(){
setTimeout(function() {
crono();
$('.datePoste').each(function(){
$(this).load('in_live.php','in_live='+$(this).attr('id'))
});
}
,10000);
}
}

Related

Javascript SetTimeout Function Not Pausing After Execution

I am checking for a change in a CSS class. I want the check to happen every 1000 milliseconds. Currently in the Google Chrome console, I can see it checking without any delay, causing the webpage to crash. What is the issue with the below setTimeout function? Perhaps there is another way of checking for a change in a CSS class also?
var itemInfo = null;
itemInfo = document.getElementById('option-item-info');
while (itemInfo.className == "disabled") {
console.log("Test 1");
getOptionItemInfo();
}
function getOptionItemInfo() {
setTimeout(function() {
console.log("Checking...");
itemInfo = document.getElementById('option-item-info');
}, 1000);
}
Your while loop isn't going to wait for the setTimeout async callback, it's just going to trigger tons of setTimeouts until your browser crashes. Instead, just kick off the setTimeout once and then only call it again from within the callback if you haven't met the desired condition.
getOptionItemInfo();
function getOptionItemInfo() {
setTimeout(function() {
console.log("Checking...");
var itemInfo = document.getElementById('option-item-info');
if (itemInfo.className == "disabled") {
getOptionItemInfo();
} else {
console.log("done!");
}
}, 1000);
}

Calling two javascript functions one from each other

I have two functions for eg., runslider() and runslider1().
runslider() runs after the document is loaded and I need to call runslider1() after finishing runslider(). Then again runslider() after runslider1(). This process should happen like infinite loop. Can someone help me please.
I have tried to keep them like callbacks. But that didn't work.
function runSlider(runslider1){
alert("run")
runSlider1(runSlider());
}
function runSlider1(runslider){
alert("run1");
runSlider(runSlider1());
}
if you want your functions to be called over and over again try using setInterval
function runSlider(){
alert("run");
runSlider1();
}
function runSlider1(){
alert("run1");
}
setInterval(runSlider, 100);
This will cause both functions to be called in that order repeatedly every 100ms. It seems like this is the behavior you are looking for.
The comments above are correct - you will cause a stack overflow.
Don't know why you would need this, but I cleaned your code for you:
function runSlider() {
alert('run');
runSlider1();
}
function runSlider1() {
alert('run1');
runSlider();
}
You can create infinite loop like this you just need to call one function.
var runSlider = function() {
console.log("run")
runSlider1()
}
var runSlider1 = function() {
console.log("run1");
setTimeout(function() {
runSlider()
}, 1000)
}
runSlider()
Another solution is:
function runSlider() {
console.log("run");
runSlider1();
setTimeout(runSlider1(), 1000) // Calls runSlider1() after 1 second(1000 millisecond). You can change it.
}
function runSlider1() {
console.log("run1");
setTimeout(runSlider(), 1000) // Calls runSlider1() after 1 second(1000 millisecond).
}
runSlider(); // Starts the cycle
var maxCalls = 0;
function run1(cb) {
alert('run1');
if (maxCalls++ < 5) { //Added this to avoid an infinite loop
cb(run1); //We want the function run after cb to be this one
}
}
function run2(cb) {
alert('run2');
if (maxCalls++ < 5) {
cb(run2);
}
}
This is the way to call one function from another. If you create an infinite loop, you will freeze the browser up. If you want the two functions running constantly, its best to release execution for a bit with a setInterval call instead.
var runFunc = 0;
var run1 = function() {
alert('run1');
};
var run2 = function() {
alert('run2');
};
var run = function() {
!(++runFunc) ? run2 : run1; //Alternate between calling each function
}
var stopRunning = function() { //Call this to stop the functions running
clearInterval(runInterval);
};
var runInterval = setInterval(run, 1000); //Calls the function every second

How to wait (for 2 seconds) after the completion of function?

I have javascript function which executes and after the execution i want to wait for 2 seconds. Is it possible in Javascript or not.
My Question is different. I want to wait after function gets executed or completed its execution not for till the function executes.
Javascript function
function ajax_closeCall(onDone) {
// alert("Close Call invoked.");
closeCall_onDone = onDone;
var closeCallUrl = soapUrl + "?action=closeCall&parentSessionId=" + parentSessionId;
closeCall_http_request = getNewHttpRequest('text/plain');
closeCall_http_request.onreadystatechange = callback_ajax_closeCall;
// http_request.open("POST", soapUrl, true);
closeCall_http_request.open("GET", closeCallUrl, true);
closeCall_http_request.send(null);
}
function callback_ajax_closeCall() {
if (closeCall_http_request.readyState != 4) {
return;
}
if (closeCall_http_request.status == 200) {
if (closeCall_onDone) {
closeCall_onDone();
}
stopMonitorCallState();
ajax_getCallState();
} else {
// there was a problem with the request,
// for example the response may be a 404 (Not Found)
// or 500 (Internal Server Error) response codes
alert(getLabel("cmmm_error_closecallfailed"));
}
}
After the above function executes, wait for 2 seconds.
How to achieve this scenario.
You wrap the code in a setTimeout:
setTimeout(function() {
// do your thing!
}, 2000);
you can use setInterval
setInterval(function(){
// write down your function that would you want to call after 2 seconds
}, 2000);
setTimeout gives you asynchronous wait time. for a function.
If you want to halt everything for two second. You can use the following trivial solution :
var date = new Date();var i;
for (i = date.getTime(); i<= date.getTime() + 2000; i = (new Date()).getTime()){/*Do Nothing*/}
Try this
call a function and then setTimeOut
function someFunction() //caller
{
one(); //call function one which will call second function from it
setTimeout(function()
{
//wait for 2 secs, do nothing
}, 2000);
}
// two functions after which you want to wait for 2 secs
function one()
{
two(); //it will call the second function
}
function two()
{
}
there is setTimeout function
setTimeout(function,milliseconds,param1,param2,...)
and you could use also setInterval function also
setInterval(function, milliseconds);

js: how to stop a loop after 1 second?

I try to write a function that shakes/nudges a window popup
this.nudge = function() {
var stopped = false;
var x=10;
setTimeout(function() {
stopped = true;
},1000);
for (i=0;;i++){
if (stopped) break;
window.moveBy(0,x)
window.moveBy(x,0)
window.moveBy(0,-x)
window.moveBy(-x,0)
}
}
Problem is : it never stops !
Since JavaScript is single-threaded (as #Luaan mentioned in the comments), your infinite loop will run infinitely and prevent any timeouts or other events from being executed. The runtime won't even try to preempt your loop (break it in the middle to run other code) and will wait until your main function has returned -- which never happens.
You cannot use a busy wait or other, similar loops in JS: they prevent the browser's UI from responding and will cause any events to be deferred until execution has finished and the script thread is free.
To process your loop correctly in an event-friendly fashion, you can either set it up as a timeout every repetition or an interval, like:
this.nudge = function() {
var x = 10;
var loop = setInterval(function() {
window.moveBy(0,x)
window.moveBy(x,0)
window.moveBy(0,-x)
window.moveBy(-x,0)
}, 100);
setTimeout(function() {
clearInterval(loop);
}, 1000);
}
This simplifies your code by removing the stopped variable and simply started/clearing a deferred loop when the timeout has expired. You can adjust the timing on either function to change the rate of animation and overall duration.
What do you think about such solution?
var i = 0;
(function a(timeout, startTime) {
console.log(i++);
if (Date.now() - startTime > timeout) return;
setTimeout(function() {
/* window.moveBy(0, x);
window.moveBy(x, 0);
window.moveBy(0, -x);
window.moveBy(-x, 0); */
a(timeout, startTime);
}, 0);
})(1000, Date.now());
Maybe you need something lie this :
this.nudge = function() {
var x=10;
var ts = Date.now();
while(Date.now()-ts<1000){
window.moveBy(0,x)
window.moveBy(x,0)
window.moveBy(0,-x)
window.moveBy(-x,0)
}
}

Implementing timeouts for node.js callbacks

This is a typical situation in node.js:
asyncFunction(arguments, callback);
When asynFunction completes, callback gets called. A problem I see with this pattern is that, if asyncFunction never completes (and asynFunction doesn't have a built-in time-out system) then callback will never be called. Worse, it seems that callback has no way of determining that asynFunction will never return.
I want to implement a "timeout" whereby if callback has not been called by asyncFunction within 1 second, then callback automatically gets called with the assumption that asynFunction has errored out. What is the standard way of doing this?
I'm not familiar with any libraries that do this, but it's not hard to wire up yourself.
// Setup the timeout handler
var timeoutProtect = setTimeout(function() {
// Clear the local timer variable, indicating the timeout has been triggered.
timeoutProtect = null;
// Execute the callback with an error argument.
callback({error:'async timed out'});
}, 5000);
// Call the async function
asyncFunction(arguments, function() {
// Proceed only if the timeout handler has not yet fired.
if (timeoutProtect) {
// Clear the scheduled timeout handler
clearTimeout(timeoutProtect);
// Run the real callback.
callback();
}
});
You probably need to come out with a solution of your own. Like
function callBackWithATimeout (callback, timeout) {
var run, timer;
run = function () {
if (timer) {
clearTimeout(timer);
timer = null;
callback.apply(this, arguments);
}
};
timer = setTimeout(run, timeout, "timeout");
return run;
}
and then
asyncFunction(arguments, callBackWithATimeout(callback, 2000));
You could do something like this:
function ensureExecution(func, timeout) {
var timer, run, called = false;
run = function() {
if(!called) {
clearTimeout(timer);
called = true;
func.apply(this, arguments);
}
};
timer = setTimeout(run, timeout);
return run;
}
Usage:
asyncFunction(arguments, ensureExecution(callback, 1000));
DEMO
But note the following:
The timeout is started immediately when you call ensureExecution, so you cannot cache that function reference.
The arguments passed to the callback will differ. For example asyncFunction might pass some arguments to callback upon success, but if the function is called by the timeout, no arguments will be passed. You have to keep that it mind. You could also provide default arguments with which the function should be called in this case:
function ensureExecution(func, timeout, args, this_obj) {
// ...
timer = setTimeout(function() {
run.apply(this_obj, args);
}, timeout);
//...
}
I ran into the same problem with a content script trying to open the port on the BG extension before the BG extension was ready. A work around was to wait for the BG extension to reply to a message and repeat this till successful. Here are the code snippets.
Content Script:
var nTimes = 10;
var bIsReady = false;
checkBGReady();
function checkBGReady() {
if (!bIsReady) {
chrome.runtime.sendMessage({msgText: "hello "+nTimes}, function(response) {
if (response && response.ack) {
console.log("have response:"+response.ack+" "+nTimes);
bIsReady = true;
// continue with initialization
bootStrap(sURL);
checkReady();
} else {
console.log("have no ack response %o",response);
}
});
}
nTimes -= 1;
if (nTimes > 0 && !bIsReady) {
setTimeout(checkBGReady,100);
}
}
BG Extension
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log(sender.tab ?"from a content script:" + sender.tab.url :"from the extension");
if (request.msgText) {
console.log("Have msg "+request.msgText);
sendResponse({ack: "have contact "+request.msgText});
}
});
In my case it usually took after the first 100ms delay.

Categories

Resources