I have the code below.
var intervalId;
function myCallback() {
$.ajax({
url: "http://bla.html",
cache: false,
success: function(data) {
if (intervalId) {
clearInterval(intervalId);
}
if (data && data.result) {
return;
}
alert(data.result);
}
, timout: 2000
});
}
function callInterval() {
intervalId = setInterval(myCallback, 5000);
}
callInterval();
The problem is that the "clearInterval(intervalId)" doesn't seems to invalidate the interval at this right time because the message alert is shown twice.
So here is my question, is clearInterval(intervalId) asynchronous?
The point is not about being the clearInterval sync or async.
In your code you start the interval the first time, and then after every second you execute your myCallback.
Clearing the interval when you get back a response, means that during the time that the ajax request is performing, the interval is still running and will start new ajax requests.
Related
in this code i want to when div with .ch1 class changed background to answer_box_small_orange.png other bottom js lines code don't run and no ajax request sends until 3 seconds and i used
window.setTimeout(function () {}, 3000)
but it doesnt work correctly
here first of all i request and get data and it is ok
$.ajax({
type:'post',
url:'http://207.154.251.233:8039/app.php/question/get',
data:JSON.stringify({apikey:'jwebdpqodp9fgkwjebfkdpqihdqlwkndqp'}),
success:(function (response) {
var x = response;
$("#question").text(x.result.question);
$(".op1").text(x.result.options["1"]);
})
});
i inserted ajax code and some other codes in function because i want to run it every 60 seconds
function myInterval () {
$(".ch1").css('background-image','url(image/answer_box_small.png)');
var clock;
$(document).ready(function() {
clock = new FlipClock($('.clock'), 60, {
clockFace: 'Counter',
autoStart: true,
countdown: true,
callbacks: {
stop: function() {
$('#loading').fadeIn('5000');
$.ajax({
type:'post',
url:'http://79.175.166.98/',
data:JSON.stringify({apikey:'jwebdpqodp9fgkwjebfkdpqihdqlwkndqp'}),
success:(function (response) {
$('#loading').fadeOut('slow');
var x = response;
$("#question").text(x.result.question);
$(".op1").text(x.result.options["1"]);
var answer = x.result.answer;
if(answer == 1){
$(".ch1").css('background-image','url(image/answer_box_small_orange.png)');
}
window.setTimeout(function () {}, 3000);
})
});
}
}
});
});
}
myInterval();
window.setInterval(function(){
myInterval();
}, 60000);
Based on what you told me, my interpretation is that you have a setTimeout() function and a setInterval() function. The setTimeout() runs at the beginning and will wait for 3 seconds. Then call an ajax function to create new requests every 6 seconds. Your problem seems to be that your first setTimeout() is re-run after you create your first AJAX request, but you want it to stop.
Taken from W3
setTimeout Return Value: A Number, representing the ID value of the timer that is set. Use this value with the clearTimeout() method to cancel the timer.
Knowing this, we can essentially cancel a setTimout() function. In your case, the first setTimeout().
Consider this,
var firstIntervalID = setTimeout(function() {
$.ajax() {
// First AJAX ran after three seconds.
}
}, 3000);
clearTimeout(firstIntervalID);
// Your code resumes to set an interval every 60 seconds without having to worry about the three seconds set before
myInterval();
var secondIntervalID = setInterval(function(){
myInterval();
}, 60000);
Essentially, you cancel the setTimeout() when you don't need it anymore. Your application for it can be different than what I wrote, but the main idea is the same. Cancel/Clear the setTimeout() with the ID that is returned on setTimeout() with clearTimeout().
This is my ajax function
function repeatedCall() {
$.ajax({
url: '/getUrl',
complete: function(data) {
if (data.statusText != "error") {
//my actions
}
}
})
}
setInterval(repeatedCall, 5000); //To make repeated ajax calls
function updateData_function{
//I want to abort all previous ajax calls and make a new ajax call since it will update the data
}
I can use clearInterval but the pending calls are not getting aborted and hence it is not updating properly.
How can i make repeated calls and at the same time abort all the requests if it enters my updateData_function.
This updateData_function will have new values so i need to make fresh ajax request.
How can i do this? Please help!! Thanks a lot in advance!!
Using setInterval to make repetead calls is not a good practice. Assume that your previous request is not completed, then there is no point in making the same ajax call. Also, as you may know, there are possibility that the response from the previous ajax call can come after the recent ajax response. So it is always better to abort any previous ajax calls.
I think the below solutions may solve your issue:
Solution 1: Just Extentending what you have done:
var xhr
function repeatedCall() {
if(xhr){
// abort any previous calls, to avoid any inconsistency
xhr.abort()
}
xhr = $.ajax({
url: '/getUrl',
complete: function(data) {
if (data.statusText != "error") {
//my actions
}
}
})
}
setInterval(repeatedCall, 5000)
function updateData_function {
//I want to abort all previous ajax calls and make a new ajax call since it will update the data
if(xhr){
xhr.abort()
}
}
Solution 2: What I feel is a better approach
var xhr;
function repeatedCall() {
xhr = $.ajax({
url: '/getUrl',
complete: function(data) {
if (data.statusText != "error") {
//my actions
// Call the ajax call again:
setTimeout(repeatedCall, 5000)
}
}
})
}
function updateData_function {
//I want to abort all previous ajax calls and make a new ajax call since it will update the data
if(xhr){
xhr.abort()
}
// do something
}
// somewhere - to initiate the repeatedCall for the first time
repeatedCall()
I faced the same problem before as well and I was sending to many ajax calls on keyup which was leading my website to collapse. I found out the solution to setTimeout(); in to the ajax all firing and keeping firing the function clears timeout and settimeout again. This let you to fire ajax only 1 time on pressing to many time.
Edit: Ok for example I had a searchbox which was getting predefined suggestions with ajax call with onkeyup function. as I was start typing it was firing ajax call again and again and stucking. I started to cancel the one before as I firing another so fixed the situation. Here is the DEMO Doesnt matter how many time you hit the button it fires only one.
I've modified my code and this works
abortValue = false;
var xhr;
xhrPool = [];
var trying;
function abortAjax() {
$.each(xhrPool, function(idx, jqXHR) {
jqXHR.abort();
});
}
$(document).ready(function() {
fn = function() {
xhr = $.ajax({
url: '/getUrl',
beforeSend: function(jqXHR) {
xhrPool.push(jqXHR);
},
complete: function(jqXHR, data) {
if (abortValue == true) {
abortAjax()
} else {
if (jqXHR.statusText != "error" && "undefined") {
//myactions
}
}
}
});
};
var interval = setInterval(fn, 5000);
});
function updateData_function {
//I want to abort all previous ajax calls and make a new ajax call since it will update the data
abortValue = true;
abortAjax();
abortValue = false;
fn();
}
I have multiple JavaScript functions and all of them run at the same time and are running in a loop because I'm reading some data from REST API.
Is there any way to stop execution of those scripts with a button or something?
function termostat1_on_off_get() {
var request = $.ajax({
type: "GET",
url: "http://192.168.1.113:8080/rest/items/termostat1_on_off/state"
});
request.done(function(data) {
console.log("On/off" + data);
if (data == 1) {
termostat1_on_off = "Vklopljen";
$("#m_t1_vklopljen").css('background-color', '#cccccc');
$("#m_t1_izklopljen").css('background-color', '#efefef');
} else {
termostat1_on_off = "Izklopljen";
$("#m_t1_vklopljen").css('background-color', '#efefef');
$("#m_t1_izklopljen").css('background-color', '#cccccc');
}
});
request.fail(function(jqXHR, textStatus) {
console.log( "Failure: " + textStatus );
});
setTimeout(termostat1_on_off_get, 5000);
}
termostat1_on_off_get();
You can use clearTimeout() to stop an in-progress timeout from running. To do this you need to save the id returned from the setTimeout call, then provide it as a parameter to clearTimeout(), like this:
var timeout;
function termostat1_on_off_get()
{
// your ajax logic here...
// inside the callbacks:
timeout = setTimeout(termostat1_on_off_get, 5000);
}
termostat1_on_off_get();
function stopTimeout() {
clearTimeout(timeout);
}
However, you should note that AJAX polling is an anti-pattern which should really be avoided. If you need to keep the UI in sync with the server then you should look in to WebSockets or Server Side Events instead. They perform much better, and save your server from having a meltdown.
Use setInterval instead of setTimeout
var i = 0;
function log() {
console.log(i++);
}
var interval = setInterval(log, 1000);
function stop() {
clearInterval(interval)
};
<button onclick="stop()">Stop</button>
<script>
Main Function:
var interval;
function refreshId(session_to_user) {
interval = setInterval(function()
{
$('.chat-box').load("<?php echo base_url()."users/message/refresh_div/"; ?>" + session_to_user);
}, 10000);
}
in this main function I'm only going to perform my requirement here. I have a variable interval my enabling this function, and it will refresh every 10 seconds.
onclick of function
forloop
{
<a href = "" onclick="myFunction(user_id)"
}
function myFunction(user_id){
clearInterval(interval);
$.ajax({
success:function(data)
{
$('.chats').html(data);
}
})
refreshId(session_to_user);
}
If anyone clicks on href, it should clearInterval if already exists else a new Interval has to be established on click function. In my current code, it works if I click for the first time. It starts refreshing the first link for every 10 seconds, but when I click for the second time on the second link, it waits. Still, the first one gets executed and then the second one is executing. My requirement is if I click, the established setInterval has to stopped instantly and the new one has to be started on the spot same as for my next function paper_plane() also.
function paper_plane()
{
clearInterval(interval);
$.ajax({
success:function(html)
{
$('#chat').append(html);
$('.chat-input').val('');
$('.chat-input').focus();
}
});
}
var side_bar_path = "<?php echo base_url()."users/message/load_side_bar"; ?>";
$.ajax({
success : function(data)
{
$('.msg-list').html(data);
}
});
refreshId(session_to_user);
}
There is no way you can cancel the ajax request after the delay(10 seconds) is elapsed from first click handler,since it would not return the result immediately.
so the only way you can cancel the previous ajax calls before making a new ajax call is to suppress/ignore the responses of the previous ajax calls once the second link is triggered, this way you will create a scenario what your expecting.
Below i have created a small snippet which will do the scenario mentioned above.
JS Code:
var firstTimer;
//first click handler
$('#first').on('click',function () {
firstTimer= setInterval(function (){
$.ajax({
url:"http://target.org/page.html",
dataType: "POST",
data:{'name1':'davy'}
success: function(data) {
//suppress the response when timer is stopped.
if(firstTimer>0){
return;
}
//if timer is not stopped process the data
},
error :function(error) {
//handle error
}
});
},1000);
});
//second click handler
$('#second').on('click',function () {
//clear the firstTimer before staring a new timer
clearInterval(firstTimer);
var timer;
timer = setInterval(function (){
$.ajax({
url:"http://target.org/page2.html",
dataType: "POST",
data:{'name1':'rog'}
success: function(data) {
//process the data
},
error :function(error) {
//handle error
}
});
},1000);
});
I have a form submitted by jQuery ajax which has error validation server side. On beforeSend I show
a gif loader and some loading text and when validation is send back on success method I show the appropriate messages for error.
This messages have timeout to hide after x seconds. Anyways when i continue clicking the submit button,
setTimeout is confusing itself and previous ones are not clearing. Here is the code I am using:
EDIT
$('form').on('submit', function(e) {
e.preventDefault();
var timer = null;
$.ajax({
beforeSend; function() {
$('.response').html('Processing form, please wait...');
},
success: function(data) {
if(data.error == true) {
$('.response').html('An error occurred.');
} else {
$('.response').html('Thank you. Form submitted successfully.');
}
if(timer) { clearTimeout(timer) };
timer = setTimeout(function() {
$('.response').html('* Indicates required fields.');
}, 10000);
}
});
});
Any suggestions appreciated.
The timer variable is scoped to your success function, so it's always null when your code to clear the old timeout is reached. Move the declaration of timer outside your AJAX call, and it should work.
var timer = null;
$.ajax({
beforeSend: function() { ... },
success: function(data) {
if(timer) { clearTimeout(timer) };
timer = setTimeout(myfunction, 10000);
}
});