I have a timer, and a function that retrieves data everytime the user clicks certain buttons. To avoid rapid succession of retrieving data
So I have a timer
var timer;
Then a function to update something via ajax
function doTheThing(data){
clearTimeout(timer);
$.ajax({
url:'/post/url',
data:data,
}).done(function(data){
timer = setTimeout(function(){
getMoreData();
},2000);
});
}
Theoretically this should start the timer on every request, but if the user successively hits buttons to cause multiple requests, it will clear the last, and start fresh. Inside the timer, I have the getMoreData(), to hopefully only retrieve once, if the user presses buttons 2 or more times successively.
function getMoreData(){
...another ajax request, which I only really want to fire once,
... if the user presses buttons very fast to trigger that first one
}
However, this isn't working. I am getting just as many requests to getMoreData(), as I am button presses.
So my timer isn't working. Whats the deal??
Your current implementation is not working is because you're clearing the timeout in doTheThing(data). There's a delay for every ajax request. So if you click rapidly, the clearTimeout will be called before any setTimeout is registered and basically does nothing.
Consider moving it to your getMoreData method, sample
function getMoreData(){
clearTimeout(timer);
timer = setTimeout(...)
//Your other ajax
}
Related
I'm building a web app to help with a restaurant, and my client was very clear on that he wanted the app to be asynchronous.
During localhost development I used setInterval to update the page periodicaly using variations of this code for each button:
$('#showWaitlist').click(function(){
showWaitlist();
stopUpdate(interval);
interval = setInterval(function() { showWaitlist();}, intervalTime);
});
function stopUpdate(){
clearInterval(interval);
}
So that every time I click a button it stops the past interval and starts it's own.
It worked fine, however, when I moved the app to the server the intevals would sometimes overlap each other, specially when the server was on heavier-than-avarage load or when I used a phone to access the site.
If setInterval and stopUpdate are js shouldn't they work on clientside and be practically instant? What could cause this "jumping" between intervals?
This is a link to the website: http://www.emc2.mx/Pruebas/unicenta/PostodoroApp/
Please note that the problem not always happens, but you can probably replicate it if you opne it on your phone.
I'll add showWaitlist here, but I doubt there's something wrong with it.
function showWaitlist(){
$.ajax({
type:'GET',
url: 'waitlist.php',
dataType: 'html',
success: function(result){
$('#result_table').html(result);
} // End of success function of ajax form
}); // End of ajax call
}
You will need to clear the interval in
the success of the ajax call on your code by adding the following line
clearInterval(interval); // stop the timer once the time finishes.
after the following line
$('#result_table').html(result);
You need to have access of the interval variable in the success method callback
I have a page with a list of items for the user to complete in a queue. Items get added into the database, and I need this list to be updated and reflect those changes on a regular basis (perhaps every minute).
I don't want to add a meta refresh to the page, because I want to avoid reloading the page. I already have a function that updates the list via ajax, so I'd like to call this function every minute.
Once the page is initially loaded, how can I repeatedly call this function without doing a blocking javascript loop? Is there a way to pause the setInterval or something to allow the rest of the queue pool to execute?
I'm worried about this happening:
$('document').ready(function () {
setInterval( function() {
updateList();
}, 60000);
}
A while(true) loop will indeed block the execution of all other scripts. setInterval will not.
The ideal solution would be a web socket like socket.io. With this, you could have something as simple as
socket.on("add", function (msg) {
addItem(msg);
}).on("removeItem", function (msg) {
removeItem(msg);
})
Then, on your server, you could simply socket.emit("messageType", msg);. This would prevent you from having to constantly poll the server with AJAX.
However, if that is not possible, you can fix your code with
$(document).ready(function () {
var updateInterval = setInterval(updateList, 60000);
// to clear interval: clearInterval(updateInterval);
})
where updateList is your function to poll the server via AJAX and append whatever tasks are received to the page.
You can use any of the following two:
setTimeout(expression, timeout); which executes the code/function once after the timeout. It is non blocking so you don't have to put it in a loop. You can call itself to make it execute infinitely.
function updateFunction() {
setTimeout(function() {
//update the page here
updateFunction();
}, 1000);
}
Or you can use setInterval(expression, timeout); which executes the code/function in intervals, with the length of the timeout between them.
setInterval(function() {
//update the page here
}, 1000);
Summing up from the comments:
You should get rid of while(true), it is blocking the rest of the code.
The setInterval() will be executed every 1min. anyway.
Note that after removing the while, the setInterval() will not block the rest of the code.
I have two checkboxes on selection of each one will raise a ajax request in order to get response from server. I need to call a method only once when there is atleast 2 seconds gap after the last request is made. Any idea? This means i do not want to call the methods when checkboxes are clicked continously for less than 2 seconds gap. How can i cancel the request made if the time gap between the requests in less than 2 seconds. Note that i want the method to be fired only once after the last request is not followed by other requests for 2 seconds.
var timeout;
clearTimeout(timeout);
timeout = setTimeout(function () { // call method }, 2000);
Note that i wan to excecute the method only once for the last request made.
You don't show any code, but assuming you already have a function doAjax() that does the ajax request, you can ensure it isn't called until two seconds after the last click in any two second period by using the setTimeout() function to do something like this:
var timerID;
document.getElementById("yourCheckboxIdHere").onclick = function() {
clearTimeout(timerID);
timerID = setTimeout(doAjax, 2000);
};
Note that doAjax does not have parentheses after it when passed as a parameter to the setTimeout() function.
If you need to pass parameters to your doAjax() function change the line with setTimeout() to:
timerID = setTimeout(function(){
doAjax(parameters, go, here);
}, 2000);
I've made script which change information from different site, its occure when i click on button, sometimes it takes 1-2 seconds to find info and display it, sometimes 10 or more seconds. i made a script which change some table rows etc in timeOut 5 seconds, how can i set timeOut if i dont know how long this search will go
$("div.dreamcast input.btn").click(function() {
$.ajax({
success: function () {
setTimeout(function() {
//i want to change results information here
$('table.itt_results tbody tr:first th:contains("etc")').hide();
},
5000 //timeout 5s
);
});
Within the succes function of the jQuery ajax call, the code gets executed as soon as the AJAX call has been successful. This way, you don't have to know how long it takes, it will always be fine.
So no need for a setTimeout here.
The success method will only be executed when you have the result so you don't need the timeout function there.
The success function will only run when the ajax function has finished successfully. There's no need to guess how long it will take.
I've set up an AJAX page refresh with setInterval.
From time to time, the server is so slow that a new request is initiated before the previous one has completed.
How can I prevent that?
Use a timeout value that is shorter than your refresh interval. When the request times out, it will call the error handler so you'll need to differentiate between time out errors and other types of errors in the handler.
$.ajax({
type: "POST",
url: "some.php",
data: "name=John&location=Boston",
timeout: 5000, /* ms or 5s */
success: function(msg){
alert( "Data Saved: " + msg );
}
});
Docs at jquery.com. Example above from same source, but with added timeout value.
Use setTimeout instead, initiate another setTimeout only after receiving the result of the AJAX request. That way a refresh only happens after the specified period since the last refresh.
Instead of using a fixed, hard coded interval: Trigger the next refresh as the last step of handling the current one, e.g. in the "Success" (or "Complete") event callbacks.
You could add a variable that keeps track of the time the current request was sent, so that you can calculate a dynamic delay:
take current time T1
send asynchronous request
other stuff happens...
asynchronous request returns, callback executes
subtract T1 from current time
if result < your desired request interval, set delay value > 0
if result >= your desired request interval, set delay value = 0
call setTimeout with the delay value, initiating the next cycle
What I can tell you is, use a flag in your code.
Like (not what I actually recommend just a simple example)
var isWorking = false;
function doRequest(){
if(isWorking) return;
isWorking = true;
$.ajax({
...,
success: workWithResponse
});
}
function workWithResponse(){
/* doAnythingelse */
isWorking = false;
}
setInterval(doRequest,1000);
Something like that, its primitive but you will avoid race conditions.
Regards.