Stop javascript function which is executing all the time - javascript

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>

Related

Is JavaScript clearInterval asynchronous?

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.

How to make repeated ajax calls and abort all the previous calls which is not finished yet when it enters some particular function?

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();
}

Jquery - check if element is not empty

I am trying to get the value of a div and then output it using jquery. However, it doesn't seems to work.
Here is my code:
<div id="container">
<p id="textbit"></p>
</div>
<script type="text/javascript">
$(document).ready(function() {
var barcode = $('#textbit');
var container = $('#container');
setTimeout(function() {barcode.text('1233')}, 5000);
barcode.each(function() {
if (barcode.html().length > 0) {
var codereader = barcode.text();
container.hide(100);
alert('The code is '+ codereader);
}
});
});
</script>
It works when I don't have the setTimeout function but this div will be populated dynamically using AJAX in future.
Any help with this would be greatly appreciated!
Javascript is single threaded and setTimeout function is an asynchronous function. It doesn't delay the code execution for 5000ms as you think. It only schedules the callback function to be executed after a 5000ms.
After scheduling the callback to be executed, javascript will keep executing the code below the setTimeout function. After 5000ms when the callback is executed, the code below the setTimeoutYou is already executed. When you try to fetch the value, the html is not set yet as it's been scheduled to set after 5000ms.
If you want to simulate AJAX time delay, you may move the code for getting value into a new function and call it in the settimeout callback like this.
$(document).ready(function() {
var barcode = $('#textbit');
var container = $('#container');
var success = function(){
barcode.each(function() {
if (barcode.html().length > 0) {
var codereader = barcode.text();
container.hide(100);
alert('The code is '+ codereader);
}
}
setTimeout(function() {
barcode.text('1233');
success();
});
}, 5000);
});
In that case you need to check in the "done" promise which will be executed after the AJAX completes.
similarly like this .
$(document).ready(function() {
var barcode = $('#textbit');
var container = $('#container');
setTimeout(function() {
barcode.text('1233');
barcode.each(function() {
if (barcode.html().length > 0) {
var codereader = barcode.text();
container.hide(100);
alert('The code is '+ codereader);
}
});
}, 5000);
});
Ajax is a asynchronous, the execution will continue to next line, and later point when it completes. The callback provided will be executed. You need to make this execution in sequence.
use ajax complete event: when ajax will finish its task then this code will run
complete: function( xhr, status ) {
alert( "The request is complete! now u can get other function form here" );
getvalues();
}

javascript does not reconnect to server side if connection is lost

I have Jquery+Ajax page that connects to server gets some data, and displays it. This is done all the time, function calls itself after it completes all task and starts to perform again and again. But If komputer loses internet connection everything stops. And when connections comes back again, nothing happens. Here is javascript code. How can I iprove it so it will continue to work after connection is back again.
$(document).ready(function() {
var a=1;
var max='23';
function kiosk()
{
if(a<max)
{
$.post('engine.php', { index: a },
function(result)
{
result = jQuery.parseJSON(result);
$('#main').css({'display':'none'});
$('#div_city').html(result.dest);
$('#div_price').html(result.price);
$('#div_price_pre').html('From ');
$('#div_price_after').html(' Euro');
$('#main').fadeIn(2000).delay(3000).fadeOut(2000, function()
{
$('#main').hide;
a++;
kiosk();
});
});
}
else
{
a=1;
kiosk();
}
}
kiosk();
});
I would suggest rather than using $.post you use
$.ajax({ type: "post" , success : function1() , failure: function2() }.
In function2() you can call koisk again after a timeout. and the succces would be the function you have created right now.
This link will help you understand the ajax function jQuery Ajax error handling, show custom exception messages
Eg Code snippet:
function kiosk()
{
if(a<max)
{
$.ajax({type : "POST" , url : 'engine.php',data: { index: a },
success : function(result)
{
result = jQuery.parseJSON(result);
$('#main').css({'display':'none'});
$('#div_city').html(result.dest);
$('#div_price').html(result.price);
$('#div_price_pre').html('From ');
$('#div_price_after').html(' Euro');
$('#main').fadeIn(2000).delay(3000).fadeOut(2000, function()
{
$('#main').hide;
a++;
kiosk();
});
},error : function (xhr, ajaxOptions, thrownError){ setTimeout(200,kiosk()) }
});
}
else
{
a=1;
kiosk();
}
}
kiosk();
});`
Using jQuery.post you are passing a callback which is executed only on success.
You should use jQuery.ajax which has different callbacks. See documentation with complete, success and error callbacks.
You could even use statusCode to map a specific HTTP code to a custom function.
Script brokes because i think it throws exception. You can add your code try and catch block, and even if has errors you can continue to try.
try {
result = jQuery.parseJSON(result);
// do your work
} catch {
// call function again
}
Or you can use, jquery ajax, it has a onerror event.

weird problem - change event fires only under debug in IE

I have form autocomplete code that executes when value changes in one textbox. It looks like this:
$('#myTextBoxId)').change(function () {
var caller = $(this);
var ajaxurl = '#Url.Action("Autocomplete", "Ajax")';
var postData = { myvalue: $(caller).val() }
executeAfterCurrentAjax(function () {
//alert("executing after ajax");
if ($(caller).valid()) {
//alert("field is valid");
$.ajax({ type: 'POST',
url: ajaxurl,
data: postData,
success: function (data) {
//some code that handles ajax call result to update form
}
});
}
});
});
As this form field (myTextBoxId) has remote validator, I have made this function:
function executeAfterCurrentAjax(callback) {
if (ajaxCounter > 0) {
setTimeout(function () { executeAfterCurrentAjax(callback); }, 100);
}
else {
callback();
}
}
This function enables me to execute this autocomplete call after remote validation has ended, resulting in autocomplete only when textbox has valid value. ajaxCounter variable is global, and its value is set in global ajax events:
$(document).ajaxStart(function () {
ajaxCounter++;
});
$(document).ajaxComplete(function () {
ajaxCounter--;
if (ajaxCounter <= 0) {
ajaxCounter = 0;
}
});
My problem is in IE (9), and it occurs only when I normally use my form. Problem is that function body inside executeAfterCurrentAjax(function () {...}); sometimes does not execute for some reason. If I uncomment any of two alerts, everything works every time, but if not, ajax call is most of the time not made (I checked this by debugging on server). If I open developer tools and try to capture network or debug javascript everything works as it should.
It seems that problem occurs when field loses focus in the same moment when remote validation request is complete. What I think it happens then is callback function in executeAfterCurrentAjaxCall is executed immediately, and in that moment jquery validation response is not finished yet, so $(caller).valid() returns false. I still do not know how alert("field is valid") helps in that scenario, and that could be sign that I'm wrong and something else is happening. However, changing executeAfterCurrentAjaxCall so it looks like this seems to solve my problem:
function executeAfterCurrentAjax(callback) {
if (ajaxCounter > 0) {
setTimeout(function () { executeAfterCurrentAjax(callback); }, 100);
}
else {
setTimeout(callback, 10);
}
}

Categories

Resources