Javascript: Call function after 10 seconds, then each 1 minute - javascript

I have the following scenario:
I have a javascript ajax function loadCars() that needs to be called after the page loads in 10 seconds, and then every 60 seconds.
The below is what I have tried so far:
setTimeout(function(){setInterval(function(){loadCars()}, 60000)}, 10000);
What is happening is that the function is being called after 10 seconds but never again, what am I missing?

You need to call loadCars on setTimeout and on setInterval.
setTimeout(function() {
console.log('first 10 secs');
// loadCars();
setInterval(function() {
console.log('60 secs has passed');
// loadCars();
}, 60000);
}, 10000);
console.log('page loaded');

I don't agree with the answers given because they use setInterval or don't wait for the ajax call to be finished. IMO your should set a new timeout only when the function loadcars (and the ajax call) has finished.
Example:
function loadCars () {
// ajax call happens here
$.ajax()
.then(function(){
// call the function here
setTimeout(function(){
loadCars();
// wait a minute after you recieved the data
}, 60000)
})
}
// wait 10 seconds
setTimeout(function(){
loadCars();
}, 10000)
The advantage if this is that it will only start setting a new timeout when the HTTP request is finished and prevent the function from getting out of sync. If you use setinterval in combination with an ajax call then the next ajax call will happen in 60 seconds even if the current one is delayed for 10 seconds (and you don't want that).

You can call setTimeout(loadCars, 60000) in your loadCars() method that way you call it once initially with setTimeout 10 seconds then from that point it sets a timeout for 1 minute out every time it executes...
function loadCars()
{
//code
setTimeout(loadCars, 60000);
}
setTimeout(loadCars, 10000);
If you want the next timeout to be scheduled only after ajax call is completed then either make a synchronus ajax call or put the setTimeout() in your success callback of your ajax call...The latter being the better option.

To get more control over timings and function calls you could specify them all this way:
function loadCars() {
$('#log').append('Cars loaded<br />');
};
function loadManufacturers() {
$('#log').append('Manufacturers loaded<br />');
};
function loadCustomers() {
$('#log').append('Customers loaded<br />');
};
function loadContent(delays, functions) {
if (functions.length) {
setTimeout(function () {
functions.pop()();
loadContent(delays, functions);
}, delays.pop());
};
};
loadContent([3000, 2000, 1000], [loadCars, loadManufacturers, loadCustomers]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id="log"></p>
Playground

Related

How setInterval runs asynchronously

I have a setInterval function that runs async code that calls the server:
setInterval(()=> {
//run AJAX function here
}, 5000);
If the server doesn't get a response within 5 seconds most probably it will run set Interval again which will then make multiple requests on the same endpoint, is there a way that the setInterval only starts its next 5 second execution after the AJAX function returns a response?
what you want to do is to use setTimeout when ever you get a response
here is some pseudo code
const doAjaxWithDelay = (delay)=>{
setTimeout(()=>{
$.ajax({
...
}).done(()=>{
// do your staff
doAjaxWithDelay(5000)
})
},delay)
}
doAjaxWithDelay(0);
Use setTimeout instead
function myTimer = () => {
setTimeout(()=> {
//run AJAX function here
ajaxFunc();
}, 5000);
function ajaxFunc() {
//case success
//do something
// case failure
// do something
// finally
myTimer();
}
myTimer()

$timeout.cancel() is not cancelling the timeout

I'm running a 3 minutes timeout and in that timeout i am running another function at particular durations.But when i'm trying to cancel the timeout its still running and the function inside it is still getting executed.Here's my code
$scope.time = 180000;
var timer = function() {
if ($scope.time > 0) {
$scope.time -= 1000;
var durations = [170000, 150000, 130000, 110000, 90000, 70000, 50000, 30000, 10000];
if (durations.includes($scope.time)) {
dataService.acceptNotify(payload).then(function(response) {
console.log(response);
if (response.data.success === true) {
$mdToast.showSimple(response.data.msg);
$mdDialog.hide();
$timeout.cancel(timeout);
}
})
}
$timeout(timer, 1000);
} else {
$mdDialog.hide();
}
}
var timeout = $timeout(timer, 1000);
You are just not capturing the timer instance into your variable, hence not cancelling it.
Try changing this line in your code:
$timeout(timer, 1000);
to
timeout = $timeout(timer, 1000);
I believe timeout is happening but you are not able to observe it. I see you are calling function timer after every 1 sec with this code
var timeout = $timeout(timer, 1000);
but you are canceling it after getting the response api and in meantime there would have been many instance started which will call that many time. so actually it's cancelling but after few times.
For example, if you get response in 20 sec, then it would be cancelled after calling api 20 times as your code is such.
I can help you with right code if you tell me what you want to do above
Just remove below code which you are using above else block.
$timeout(timer, 1000);
It will work for you.

Avoid Calling a function repeateadly unless its job is finished

I have a function that needs to be called after 5 seconds time interval. This function processes AJAX request in the background (the request goes to other website, so it may take a few seconds). The function is as follows:
function myFunction() {
var sendData = {
cid: cid
};
$.post('xyz.com/somepage.php', sendData, function(response) {
//processes the response
});
setTimeout(myFunction, 5000); //call again after 5 seconds
}
I need to consider a fact that some users may have slow internet connection and the request can take time more than 5 seconds. So, I need to avoid calling that function (or we say avoid sending request) again until its job is finished. I tried the method given in the last paragraph on this link, but it didn't work. Any suggestion? Thanks.
You can call the function on completion of ajax call
function myFunction() {
var sendData = {
cid: cid
};
$.post('xyz.com/somepage.php', sendData, function(response) {
//processes the response
}).done(function() {
setTimeout(myFunction, 5000); //call again after 5 seconds
});
}
Place the setTimeout call within the callback handler:
function myFunction() {
$.post('xyz.com/somepage.php', { cid: cid }, function(response){
//processes the response
setTimeout(myFunction, 5000);//call again after 5 seconds
});
}

How can I perform this JavaScript call after a delay time?

I am pretty new in JavaScript and I have to perform an operation after some time that another previous operation is performed.
So I have this function:
function validaProgetti() {
$.ajax({
type: "POST",
//data: {'checkedRowList' : checkedRowList},
data: JSON.stringify(checkedRowList),
url: "validaProgetti",
contentType:"application/json"
}).done(function(response) {
$('.modal').modal('hide');
sostituisciFrammentoJsp('outputRicerca', response);
//alert("SUCCESS");
}).error(function(xhr) {
alert("ERROR");
manageError(xhr);
});
}
As you can see into the done() body I have these 2 call:
$('.modal').modal('hide');
sostituisciFrammentoJsp('outputRicerca', response);
I need that the sostituisciFrammentoJsp() execution is performed after 3 seconds of delay to ensure that the previoius function is complete.
How can I correctly set a delay for this function?
...after 3 seconds of delay to ensure that the previoius function is complete.
Let's do better than that, and actually wait for the previous function to complete:
$('.modal').modal('hide').one("hidden.bs.modal", function() {
sostituisciFrammentoJsp('outputRicerca', response);
});
(Note I used one, not on, so the handler gets autoremoved after the event occurs.)
Note that I've assumed there you're using a Bootstrap modal, but other "modal" libraries will offer a similar event or callback.
But answering the question you actually asked, you can set up a callback after three seconds with setTimeout:
$('.modal').modal('hide');
setTimeout(function() {
sostituisciFrammentoJsp('outputRicerca', response);
}, 3000);
The number at the end is in milliseconds (thousanths of a second).
Just use javascript setTimeout
setTimeout(function(){
// your code here
}, timeInMillis);
Using this command will schedule an operation for the time you pass.
Option : 1
clearTimeout(window.timer);
window.timer=setTimeout(function(){ // setting the delay for each keypress
ajaxSearchRequest($type); //runs the ajax request
}, 3000);
Option : 2
// set your delay here, 2 seconds as an example...
var my_delay = 2000;
// call your ajax function when the document is ready...
$(function() {
callAjax();
});
// function that processes your ajax calls...
function callAjax() {
$.ajax({
// ajax parameters here...
// ...
success: function() {
setTimeout(callAjax, my_delay);
}
});
}

Chat application polling

I'm working on a chat application, which polls the server at a timeout.
The timeout increases if, over time, there hasn't been any recent activity.
The function loadNew() performs an ajax call to the server, which responds with message data.
pollTimeoutTime = 500;
function poll() {
pollTimeout = setTimeout(function(){
loadNew();
if (!new_messages_count) {
//Increasing delay between polls as no messages are incoming to a maximum of 1 minute/60 seconds
if (pollTimeoutTime < 60000) pollTimeoutTime = pollTimeoutTime * 1.25;
}
else {
//Reset delay between poll to default of 0.5 seconds
pollTimeoutTime = 500;
}
poll();
},pollTimeoutTime);
}
The problem I'm having is that the timeout function does not wait for the function loadNew() to complete, which causes the same poll to be sent twice or more if the timeout is lower than the time it takes for the ajax call in the function to complete.
The server thus responds with the same data multiple times, which leads to duplicative display of messages in the chat.
Is there a way to make the timeout only trigger after loadNew() has finished fetching and displaying the data?
EDIT: after using #Brad M's answer, it doesn't duplicate messages anymore. I would still like to have a way to call for a poll after the user submits a message, so the new message is displayed immediately. This would interfere with the timeout set in loadNew(), which would cause messages to be duplicated again. Could you think of a way to get that working?
Without seeing your loadNew function, an easy fix might be to change that function to return your ajax call (return $.ajax({...});) and change the code you posted to this:
pollTimeoutTime = 500;
function poll() {
pollTimeout = setTimeout(function () {
loadNew().done(function (result) {
if (!new_messages_count) {
//Increasing delay between polls as no messages are incoming to a maximum of 1 minute/60 seconds
if (pollTimeoutTime < 60000) pollTimeoutTime = pollTimeoutTime * 1.25;
} else {
//Reset delay between poll to default of 0.5 seconds
pollTimeoutTime = 500;
}
poll();
});
}, pollTimeoutTime);
}
Use ajax callback functions such as success or complete to trigger a new poll.

Categories