I want to add a class (this class put a spinner in an input, but thats not the problem) when the ajax poll takes more than x seconds (probably 1500 ms). I've tried with a setInterval and then, when the poll finishes I close the interval. But this didn't run.
I use jquery to do the ajax call and I use the property "async: false", this could be the problem? If I remove this my code doesn't run well so I need the ajax poll "sync".
Thats my code:
function calcvat(){
message_timer = setTimeout(function(){
$('.js-vatinput').addClass('changing');
}, 1000);
if(isValidVAT()){ //In this function is the ajax
....
}
}
function isValidVAT(){
...
$.ajax({
data: {...},
type: "POST",
dataType: "json",
async: false, //This could be the problem?
url: url,
}).done(function( data, textStatus, jqXHR ) {
...
$('.js-vatinput').removeClass('changing');
clearInterval(message_timer);
message_timer = false;
}
....
}
Thank you for your time!
Yes, the async: false is the problem. By using async: false, you force the browser to suspend the main UI thread while the ajax call is being done. No UI updates will be allowed, no other JavaScript code can run, etc., until the ajax call completes.
async: false is never correct. At best it makes for poor UX in any case (it freezes the tab at least, and also possibly other related tabs; on older browsers [such as IE8] it froze the whole browser UI).
Remove the async: false and (inferring from your code) just disable sending the form / performing the action that this validation is a part of while the ajax call is pending instead.
Side note 1: 1.5 seconds is a long time to wonder whether something is happening. Suggest feedback within 250ms at the latest; immediate feedback is generally better.
Side note 2: I assume message_timer is declared somewhere. :-) If not, the code is falling prey to what I call The Horror of Implicit Globals and you'll want to declare it somewhere that both of those functions have access to it (but not, ideally, globally).
I have a python script that's doing around 8 or 9 specific steps. These steps are being logged in a file. For web GUI to display status change, or error messages, I am using the script belowjquery PeriodicalUpdater plugin.
I need the program to run simultaneously so that as the value in the file changes,it gets polled and displayed.
Please find my jquery code below.
Note the url "/primary_call/" takes around 2 and half minutes to execute. Problem is async :false is not working. The browser waits for 2.5 minutes, and then gets into the next level.
I tried in Firefox and Chrome and it gives the same result.
When I call the URL of another browser tab, it works perfectly, but I am unable to run both script components simultaneously, when I try calling from the same page.
What should I do so that the browser initiates "/primary_call/", which runs a Python script in the background, at the same time moving ahead to the portion called PeriodicUpdate.
$(document).ready(function()
$.ajax({
type: 'GET', // Or any other HTTP Verb (Method)
url: '/primary_call/',
async: false,
success: function(r){
return false;
},
error: function(e){
}
});
$.PeriodicalUpdater({
url : '/static/12.txt',
method: 'post',
maxTimeout: 6000,
},
function(data){
var myHtml = data + ' <br />';
$('#results').append(myHtml);
});
})
Setting async:false means you are making the process synchronous, so the browser will hang on it until it is finished -- it can't move on to your other method. Removing that option will make the call asynchronous (which it is by default, as it should be) at which point the browser will initialize each ajax call in a separate thread.
In short, remove async:false.
I'm trying to perform a post query when the user leaves the page. The code I'm working with is
<script type="text/javascript">
window.onbeforeunload = function(){
var used = $('#identifier').val();
$.post('conversation.php?leave=true',{ud:used});
}
</script>
Is there anything wrong with what I'm doing here? The result I get in the FF error console is just saying that other non-related functions/variables are not defined (since they are unloading). Any tips or pointers for what I need to fix?
The simple answer is you can't make an asynchronous AJAX call in the beforeunload event reliably, it'll very likely be terminated before it finished, as the browser garbage collects the page. You can make a synchronous call, like this:
$.ajax({
type: "POST",
url: 'conversation.php?leave=true',
data:{ud:used},
async: false
});
Please don't do this though, as it traps your user in the page for longer than needed and prevents them from leaving, resulting in a negative experience. Note that this also locks up the browser while it executes, async: false should be avoided in every case possible.
given to certain circumstances, I'm forced to keep page settings (Javascript-values) in the session and it has to be done right before leaving the page (I can't use cookies, since "pageSettings" can become quite large and localStorage is not an option yet ;) ). So this is how I tried it. However it seems that when I call the page directly again, the call of "http://blabla.com/bla" happens asynchronous, even though the async-attribute is set (I don't receive the settings of the previous call, but of the one before):
$jQ(document).ready(function () {
$jQ(window).unload(Main.__setSessionValues);
});
var Main = {
pageSettings: {},
__setSessionValues: function __setSessionValues() {
$jQ.ajax({
type: "POST",
async: false,
url: "http://blabla.com/bla",
data: {
pageSettings: Object.toJSON(Main.pageSettings)
}
});
}
};
Does anyone know what the problem might be?
thanks in advance
The code looks fine. You might try bind('beforeunload', ...) rather than unload, to grab things as early as possible. But of course, if something else also hooks beforeunload and the unload gets cancelled, your call will have been made even though you're still on the page.
Slightly off-topic, but if you can possibly find a different way to do this, I would. Firing off synchronous ajax calls when the user is trying to leave the page is not ideal.
I'm just starting to wean myself from ASP.NET UpdatePanels. I'm using jQuery and jTemplates to bind the results of a web service to a grid, and everything works fine.
Here's the thing: I'm trying to show a spinner GIF while the table is being refreshed (à la UpdateProgress in ASP.NET) I've got it all working, except that the spinner is frozen. To see what's going on, I've tried moving the spinner out from the update progress div and out on the page where I can see it the whole time. It spins and spins until the refresh starts, and stays frozen until the refresh is done, and then starts spinning again. Not really what you want from a 'please wait' spinner!
This is in IE7 - haven't had a chance to test in other browsers yet. Any thoughts? Is the ajax call or the client-side databinding so resource-intensive that the browser is unable to tend to its animated GIFs?
Update
Here's the code that refreshes the grid. Not sure if this is synchronous or asynchronous.
updateConcessions = function(e) {
$.ajax({
type: "POST",
url: "Concessions.aspx/GetConcessions",
data: "{'Countries':'ga'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
applyTemplate(msg);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
}
});
}
applyTemplate = function(msg) {
$('div#TemplateTarget').setTemplate($('div#TemplateSource').html());
$('div#TemplateTarget').processTemplate(msg);
}
Update 2
I just checked the jQuery documentation and the $.ajax() method is asynchronous by default. Just for kicks I added this
$.ajax({
async: true,
...
and it didn't make any difference.
It's not the Ajax call that's freezing the browser. It's the success handler (applyTemplate). Inserting HTML into a document like that can freeze IE, depending on how much HTML there is. It's because the IE UI is single threaded; if you notice, the actual IE menus are frozen too while this is happening.
As a test, try:
applyTemplate = function(msg) {
return;
}
I don't remember precisely what caused it, but we had a similar issue with IE6 in a busy box and we fixed it with this incredible hack in the Javascript:
setTimeout("document.images['BusyImage'].src=document.images['BusyImage'].src",10);
That just sets the image source to what it was before, but it is apparently enough to jostle IE out of its stupor.
edit: I think I remember what was causing this: We were loading the animation into a div with display: none. IE loads it and doesn't start the animation, because it's hidden. Unfortunately it doesn't start the animation when you set the containing block to display: block, so we used the above line of code to trick IE into reloading the image.
The image freezes because while it is hidden the animation is disabled by IE.
To fix this, append the loading image instead of unhiding it:
function showLoader(callback){
$('#wherever').append(
'<img class="waiting" src="/path/to/gif.gif" />'
);
callback();
}
function finishForm(){
var passed = formValidate(document.forms.clientSupportReq);
if(passed)
{
$('input#subm')
.val('Uploading...')
.attr('disabled','disabled');
$('input#res').hide();
}
return passed;
}
$(function(){
// on submit
$('form#formid').submit(function(){
var l = showLoader( function(){
finishForm()
});
if(!l){
$('.waiting').remove();
}
return l;
});
});
Are you sure that its during the AJAX call that the GIF isn't spinning?
In your concessions.aspx place this line somewhere in the handling of GetConcessions:-
System.Threading.Thread.Sleep(5000);
I suspect that the gif spins for 5 seconds then freezes whilst IE renders and paints the result.
I know the question was regarding asynchronous ajax calls. However I wanted to add that I have found the following in my tests regarding synchronous ajax calls:
For Synchronous ajax calls. While the call is in progress (i.e. waiting for the server to respond). For the test i put a delay in the server response on the server.
Firefox 17.0.1 - animated gif continues to animate properly.
Chrome v23 - animated gif stops animation while the request is in progress.
well, this is for many reasons. First at all, when the ajax call back of the server, you will sense a few miliseconds your gif frozen, but not many relevant. After you will start to process information, and depending of the objects that you manipulate and how you do it, you will have more o less time your gif frozen. This is because the thread is busy processing information. Example if you have 1000 objects and your do a order, and move information, and also you use jquery and append, insert, $.each commands, you will senses a gif frozen. Sometimes it's imposible avoid all the frozen gifs, but yu can limit the time to a few miliseconds doing this: Make a list of response ajax, and process it each 2 seconds (with this you will have the results in a alone array and you wil call it with one setInterval and you avoid the bottle neck of try process one response when the before response is still processing). if you use JQuery don't use $.each, use for. Don't use dom manipulation (append,insert,etc..), use html(). In resume do less code, refactor, and procdess all the response (if you did more of 1) like only 1. Sorry for my english.
I had a similar problem with the browser freezing. If you are developing and testing locally, for some reason it freezes the web browser. After uploading my code to a web server it started to work. I hope this helps, because it took me hours to figure it out for myself.
I have seen this behavior in the past when making AJAX calls. I believe this is related to the fact that browsers are only single threaded, so when the AJAX call is returned the thread is working on the call, so consequentially the animated GIF needs to stop momentarily.
dennismonsewicz's answer is greate. Use spin.js and the site http://fgnass.github.com/spin.js/ shows the step which is quite easy.
Under heavy process we should use CSS animations.
No JS driven animations and GIFs should be used becacuse of the single thread limit otherwise the animation will freeze. CSS animations are separated from the UI thread.
Are you doing a synchronous call or asynchronous call? synchronous calls do cause the browser to seemingly lock up for the duration of the call. The other possibility is that the system is very busy doing whatever work it is doing.
Wrapping ajax call in setTimeout function helped me to prevent freezing of gif-animation:
setTimeout(function() {
$.get('/some_link', function (response) {
// some actions
});
}, 0);
Browsers are single-threaded and multi-threaded.
For any browser :
When you a called a function that contains a nested ajax function
java/servlet/jsp/Controller >
keep Thread.sleep(5000); in servlet to understand the async in ajax when
true or false.
function ajaxFn(){
$('#status').html('WAIT... <img id="theImg" src="page-loader.gif" alt="preload" width="30" height="30"/>');
$('#status').css("color","red");
$.ajax({
url:"MyServlet",
method: "POST",
data: { name: $("textarea").val(),
id : $("input[type=text]").val() },
//async: false,
success:function(response){
//alert(response); //response is "welcome to.."
$("#status").text(response);
$('#status').css("color","green");
},
complete:function(x,y){
//alert(y)
},
error:function(){
$("#status").text("?");
}
});
}