Timer in Ajax - Preemption [duplicate] - javascript

This question already has an answer here:
Ajax too slow - Recursion
(1 answer)
Closed 4 years ago.
So this thing was going in my mind for a long time whether the timer that is given in an AJAx after which it has to send another request, what if it is smaller than the actual time taken by the requested file to complete its operation.
for example, consider the below code,
<div class="item"></div>
<script>
function timeLeft() {
$(".item").each(function() {
$this = $(this);
var dataString = {s: "//some data", st: "<?echo $stamp?>"};
$.ajaxSetup({cache:false});
$.ajax({
type: "POST",
url: "get_content_home.php",
dataType: "html",
data: dataString,
success: function(result) {
$this.html(result);
}
});
});
}
window.setInterval(function() {
timeLeft();
}, 100);
</script>
the timer given here is 100ms and the file get_content_home.php will be requested every 100m. What if get_content_home.php takes 500ms to complete its operations. Will the get_content_home.php be preempted and will be requested again? or will the timer wait and delay itself.
Thanks in advance.

It's worse than you thought since the ajax request is in a loop.
What's gonna happen is actually :
window.setInterval call timeLeft
timeLeft call the AJAX request to get_content_home.phpone time for each .item element.
Let's say one AJAX call take 500ms, you'll do this five time before the first AJAX request return something (hence 5xnumber of .item calls before one result).
To stop this craziness, put your AJAX call outside of the loop and put the window.setInterval in the AJAX callback function:
$.ajax({
type: "POST",
url: "get_content_home.php",
dataType: "html",
data: dataString,
success: function(result) {
$this.html(result);
window.setTimeOut(function() {
timeLeft();
}, 100);
}
});
and call timeLeft(); just once at the start.

Related

Run ajax request after specific time

Hello I'm working on a website with a color slider that append a specific color page to the DOM after a slide change. I want people to still be able to go through the different slide pretty quickly and load the ajax page only if the user didn't change the slide for a specific time (for example 1000ms).
I tried setInterval, setTimeout and the ajax timeout parameter but it isn't working, it just adds requests to the call stack and after the timeout duration it appends the div 5 times.
Here's the ajax call:
$.ajax({
url: "/wp-admin/admin-ajax.php",
type:"POST",
data: {
action: "my_custom_color",
post_link: post_ID
}, success: function (response) {
$('.color').prepend(response);
},
})
I want to be able to do something like this:
colorsMonoSlider.events.on('indexChanged', () => {
setTimeout(() => {
customizedFunction()
}, 1000);
});
But without filling the call stack (maybe emptying it at each call), the ajax request should only trigger once after the timeout, I can't disable the slider navigation or use async: false because as I said users need to be able to spam click to go through the slider fast.
Any tips welcome, thanks in advance.
You need to cancel both your ajax call and timer functions before invoking again.
Assuming the customized function has the ajax call.
var xhr,timer;
function customizedFunction(){
xhr && xhr.abort();
xhr = $.ajax({
url: "/wp-admin/admin-ajax.php",
type:"POST",
data: {
action: "my_custom_color",
post_link: post_ID
}, success: function (response) {
$('.color').prepend(response);
},
})
}
colorsMonoSlider.events.on('indexChanged', () => {
timer && clearTimeout(timer);
timer = setTimeout(() => {
customizedFunction()
}, 1000);
});

If an AJAX request takes more than 3 seconds, do something [duplicate]

Can someone show me a practical example on setting a timeout to my $.ajax request and redo the entire request if the first request is timed out, I've read the docs and didn't get it. I will appreciate any help.
Here is my $.ajax request.
$.ajax({
url: '<?php bloginfo('template_directory'); ?>/ajax/product.php',
type: 'get',
data: {product_id : product_id},
beforeSend: function(){
$('#details').html('<div class="loading"></div>');
},
success: function(data){
$('.iosSlider').fadeOut('fast');
thisprod.addClass('current');
$('#details').css({opacity: 0}).html(data).stop().animate({left: 0, opacity: 1}, 800);
}
});
return false;
The ajax function takes a timeout parameter and you can check the status in case of error.
var call =function(){
$.ajax({
url: '<?php bloginfo('template_directory'); ?>/ajax/product.php',
type: 'get',
timeout: 400,
...
error: function(x, textStatus, m) {
if (textStatus=="timeout") {
call();
}
}
});
};
You might want to make something a little smarter to avoid permanent calls...
From the documentation :
Set a timeout (in milliseconds) for the request. This will override
any global timeout set with $.ajaxSetup(). The timeout period starts
at the point the $.ajax call is made; if several other requests are in
progress and the browser has no connections available, it is possible
for a request to time out before it can be sent. In jQuery 1.4.x and
below, the XMLHttpRequest object will be in an invalid state if the
request times out; accessing any object members may throw an
exception. In Firefox 3.0+ only, script and JSONP requests cannot be
cancelled by a timeout; the script will run even if it arrives after
the timeout period.
I would use the jquery deferred fail callback for this case.
http://api.jquery.com/deferred.fail/
a. You can maintain a queue of all the requests that you make.
$.xhrQueue = [];
b. Enqueue each request that you make
$.ajaxSetup({
beforeSend: function (e, xhr) {
$.xhrQueue .push(xhr);
}
});
c. Poll for which requests completed vs timed-out
setInterval(function(){
$.each($.xhrQueue, function (xhr) {
//check whether status is complete,
//with some try-catch you can know which were the timed-out/not-sent ones
});
}, 1000);
Note: If not beforeSend, you can go via some other function through which you attempt to make an ajax call
Try this
var setTime = setTimeOut(function() {
$.ajax({
url: '<?php bloginfo('
template_directory ');?>/ajax/product.php',
type: 'GET',
data: {
'product_id': product_id
}
}).beforeSend(function() {
$('#details').html('<div class="loading"></div>');
}).done(function(data) {
$('.iosSlider').fadeOut('fast');
thisprod.addClass('current');
$('#details').css({
opacity: 0
}).html(data).stop().animate({
left: 0,
opacity: 1
}, 800);
});
}, 2000);

how to add delay function inside the ajax function

I am using ajax function to update and output the result.
how can I delay like 2 secs before the second update result get display again?
since right now, after the first update and second update, the text is the same like
'updated' I want to let user know this is the second time updated msg.
$.ajax({
type: "post",
url: "function.php",
data: "ajax=updateAward&" + inputs,
success: function(html) {
$('#message_award').html(''); //clear previous text
//delay 2 sec then display below?
$('#message_award').html(html) ;
}
});
Use setTimeout to execute a function after a delay (given in milliseconds). Here's a complete example:
$.ajax({
type: "post",
url: "function.php",
data: "ajax=updateAward&" + inputs,
success: function(html) {
setTimeout(function() {
$('#message_award').html(html);
}, 2000);
}
});

Ajax recursive function work strange

Hello guys here's my code:
var ajax={
chiamata:function(target,url,opzioni){
if (!tools.array_key_exists('caricamento',opzioni)){
opzioni['caricamento']=1;
}
var dati=url.split('?');
$.ajax({
type: opzioni['type'],
url: url,
contentType:"application/x-www-form-urlencoded; charset=UTF-8",
data: dati[1],
dataType: "html",
success: function(msg){
if (opzioni['caricamento']!=0){
ajax.printLoading();
}
$(target).html(msg);
},
error: function(){
alert("Chiamata fallita!");
}
})
},
printLoading:function(){
var body="#colonnaDX";
$(body).ajaxStart(function(){
$(body).append('<div id="loading"><img src="graphic/IMAGE/spinner.gif"/>Loading...</div>');
})
.ajaxStop(function(){
$('#loading').remove();
});
}
},
//Recursive function
var object={
checkAzione:function(target,url,opzioni,interval){
if (!interval)
interval=60000;
ajax.chiamata(target,url,opzioni);
setTimeout(function() {
this.checkAzione(target,url,opzioni,interval);
}, interval);
}
}
$(document).ready(function(){
object.checkAzione(
'#colonnaDX',
'someactions.php',{
'caricamento':0
},
10000
);
})
I'll try to explain the problem as better as i can, When the document is ready, the function "checkAzione" starts and it makes some stuff like DB calls etc, this kinds of ajax calls don't need any visual loading like spinner etc so in the array "opzioni" i set a flag 'caricamento':0 (same of 'loading':0) just check my ajax object to see what i mean, it works until i make some ajax calls that using 'caricamento':1, from that moment every ajax calls in my recursive function makes the "printLoading"... Any tips????
ajaxStart and ajaxStop are global, you add them to the body. You probably shouldn't use ajaxStart/Stop in this case, just add the functionality to your ajax listeners (success and error).

Hold ajax call in every minute calling section

i am calling ajax every second in page..
Here the server page returns randomly generated number,using this number(converted into seconds) i am triggering another function in ajax success .it works
My problem
suppose random number = 5 means trigger() function called after 5 seconds using setTimeout,but rember ajax call is triggering every 1 second so trigger function also called many time.
i want to make ajax call wait untill trigger function execution.Which means i wanna pause that ajax call untill 5 seconds after that resume
How can i do this ?
My coding
//this ajax is called every minute
$.ajax({
type: "POST",
url: 'serverpage',
data: ({pid:1}),
success: function(msg) {
var array = msg.split('/');
if(array[0]==1){
setTimeout(function() { trigger(msg); },array[1]+'000');
}
}
});
//and my trigger function
function trigger(value)
{
alert("i am triggered !");
}
server response maybe
1/2 or 1/5 or 1/ 10 or 1/1
here 1/3(this is converted into seconds)
It looks like you should fire the ajax call in your trigger function, or on the error callback. Fire it once at page ready, and then fire it when your success function is called.
function ajaxCall() {
$.ajax({
type: "POST",
url: 'serverpage',
data: ({pid:1}),
success: function(msg) {
var array = msg.split('/');
if(array[0]==1){
setTimeout(function() {
trigger(msg);
ajaxCall();
}, parseInt(array[1])*1000);
}
},
error: function() {
setTimeout(ajaxCall, 1000);
}
});
}
$(ajaxCall);
Note: you should reply with some json instead of your custom data format "1/3". Something like "{success:1,delay:3}" would be much more reliable.
you can call your ajax function recursively from your 'success' callback function or in your case better would be from trigger function.
Rather than having your AJAX call in a timer, just recall it after each execution of the trigger function.
//and my trigger function
function trigger(value)
{
alert("i am triggered !");
MyAjaxFunction();
}
You have to call it once too at page load:
$(document).ready(function(){
MyAjaxFunction();
});

Categories