Javascript variable state after ajax request [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I'm new in the web programming and I don't fully understand some simple things.
Suppose we have following ajax request:
var records = [];
$.ajax(
{
url : "index",
dataType: 'json',
success: function (response)
{
records = response;
}
});
alert(records.length);//This displays 0
alert(records.length);//This alert correctly displays number of records
The problem is that the array records appears empty, if I try to use them immediately after calling ajax (first alert displays zero length, while second alert displays correct length). What's the problem and how to solve it?

You just need to put your alert inside the success callback.
var records = [];
$.ajax(
{
url : "index",
dataType: 'json',
success: function (response)
{
records = response;
alert(records.length); // will always be correct
}
});
In your example, the behavior will be unpredictable and will depend on how fast the call returns.

The A in Ajax stands for Asynchronous
The success function doesn't trigger until the HTTP response comes back.
When the first alert fires, it hasn't come back. In the time it takes for you to click OK to that alert, the response has arrived so the success function has run by the time the second alert fires. (alert is a blocking function).
Do your work on the data in the success function, not immediately after sending the HTTP request.

Related

jQuery Ajax run, Why? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I have script following:
var price_option_oc = 0;
// Example
jQuery.ajax({
type: "POST",
processData: false,
dataType: "text",
url: mainURL + url_ajax_get_prices_oc,
data: JSON.stringify(datas),
contentType: "application/json; charset=utf-8",
}).done(function(data) {
console.log('{1}=' + data);
price_option_oc = data;
});
console.log('{2}' + price_option_oc);
Why result is, I dont know why, please explain for me
{2}0
{2}0
{1}=9
{1}=9
Why not is:
{1}=9
{1}=9
{2}0
{2}0
Thanks.
Ajax requests run asynchronously to the rest of your code. That is, they run in parallel.
So it's very likely that
console.log('{2}'+price_option_oc);
is running before the ajax call completes and runs console.log('{1}='+data);
I say "very likely" because, since the ajax call relies on external factors like network speed and the response speed of the remote server, you can't guarantee how fast it will run, and therefore you can't guarantee the order things will run in.
If you need to run code which depends on the response from an ajax call, then you must put that code into your .done function (or into a function which is called from there).
P.S. I would not use async:false to solve this type of issue - this will cause the browser to stop responding to any user input until the ajax call completes (or fails). If the call takes longer than normal, it will look to the user like their browser has crashed. This is not user-friendly. Most coders don't use this feature for that reason.

jQuery $.ajax success firing last [duplicate]

This question already has answers here:
Easy to understand definition of "asynchronous event"? [closed]
(11 answers)
Closed 7 years ago.
I have the following Javascript and it's returning results out of the order I would expect them.
function getCurrentItems(id){
alert("2");
$.ajax({
url: "somePHPurlthatspitsoutajsonencodedArray.php",
type: "POST",
dataType: "json'",
data: {id:id},
success: function(data){
alert("3");
}
});
alert("4");
}
$(document).on('click', '.eventClass', function(e){
alert("1");
var id = "someID";
var results = getCurrentItems(id);
alert("5");
});
I would think I'd get alerts in the order of 1, 2, 3, 4, 5.
Instead I get them in the order of 1, 2, 4, 5, 3.
I just can't figure out why that success alert (5) fires last?
AJAX is short for asynchronous JavaScript and XML. Asynchronous is the keyword here. I'll use an allegory to explain async.
Lets say you're washing dishes manually. You can't do anything else while doing that, so it is synchronous.
Lets say you put your dishes in a dishwasher. You can do other things, you've delegated the task to the dishwasher, so this is asynchronous. Asynchronous is generally better, because you can do multiple things at one time. Javascript only asyncs when requesting info from the server, as Javascript is single threaded (it only runs on 1 CPU core and can only do one thing at a time on it's own).
A callback is a function that is called when the async task completes. The dishwasher finishes, so now you have to empty it as soon as you complete what you're doing when it finshed.
So in your code, you start the dishwasher, say you're going to alert("3") when the dishwasher finishes running, and then you go alert 4 and 5. Then when the dishwasher finishes/your server returns data, you alert 3 like you said you would.
That make sense?
The reason that you give a success callback function in an ajax request is that the request might take some time to return, but your code can continue running. In this case the ajax request is sent, and the success function is remembered for later, then your code continues (alerting 4 and 5). When the browser receives the response to the ajax request it calls the success function (alerting 3).
The way that Javascript works, only one thread is run per browser tab, so event handlers are not called until any previously running code is completed. Therefore, even if your getCurrentItems function were to take several seconds to complete, by which time the server response had returned, the success function would still not be called until after your function had completed.
Edit: Because an ajax call can take some time, it is not generally desirable to be able to call a function like getCurrentItems which includes an ajax request, and wait for the response. If you do this, then you are likely to leave your browser window unresponsive, and you will have to deal with potential errors from the ajax call. Instead, you should put any code that you wish to run which relies on the ajax result in the success function, or in another function which you call from there. As languages go, Javascript is very good for doing this kind of thing. You could even take a callback function as an argument to getCurrentItems, and run it from the success function.
As others have mentioned, you're getting the results in the order you see because the ajax request doesn't return with it's data and call your success callback until the response is received, but code continues to execute immediately after the $.ajax call.
To get the workflow you're probably expecting, you could use promises, or simply pass in a callback:
function getCurrentItems(id, onSuccess){
alert("2");
$.ajax({
url: "somePHPurlthatspitsoutajsonencodedArray.php",
type: "POST",
dataType: "json'",
data: {id:id},
success: function(data){
alert("3");
onSuccess(data);
}
});
alert("4");
}
$(document).on('click', '.eventClass', function(e){
alert("1");
var id = "someID";
var results = getCurrentItems(id, function(data){
console.log('data',data);
alert("5");
});
});

jQuery .ajax or .post taking too long message [duplicate]

This question already has an answer here:
Run function if jQuery.ajax waiting for respond long enough
(1 answer)
Closed 8 years ago.
I know about the timeout setting for the ajax call. But what i'm wondering is, is there a way to display a message to the user if an ajax call is still processing but taking longer than x seconds.
E.g.
During an ajax call, if it takes longer than 10 secs tell the user, "call taking longer than expected"
I'd say your best bet is to use window.setTimeout for however long you want to wait for before showing your notification, and then add a window.clearTimeout line to your success callback in your $.ajax() call:
var loadingTimeout = window.setTimeout(function() {
// show your warning here
alert('Still loading :P');
}, 10000); // 10000ms = 10sec
$.ajax({
url: 'http://your/url/here',
dataType: 'json',
type: 'GET',
success: function(r) {
window.clearTimeout(loadingTimeout);
// your results logic here
}
})
Sure, just setTimeout() yourself another function that checks some global variable that gets set by the ajax completion callback. In that function, if the ajax call is still outstanding, show a message.

How to make a function return data retrieved via AJAX [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
In my javascript file, I use the function above to get asynchronously a value calculated by the server:
function function2(userid)
{
$.ajax({
type: "POST",
url: "http://localhost/bghitn/web/app_dev.php/get_number_of_articles",
data:{id:userid},
cache: false,
success: function(data){
return data;
}
});
}
In fact, I call the function2 inside a set of functions:
function1();
var userid=.....
var x= function2(userid);
function3(x);
The problem:
as you see, function3 uses the data returned by function2. But it seems that function3 starts executing before the AJAX call is successfully finished. I tried to use the when function but in vain.
$.when(function2(userid)).done(function(){
function3();
});
How to make the next javascript code executes after the preceding AJAX request is successfully performed? Your advices are highly appreciates.
Option 1: You can always set your AJAX call to be synchronius, but be ready that the whole page stucks while waiting for response. just add parameter async: false to your set of parameters.
Option 2: Provide callbacks or put your future code inside success handler
Option 3: You can use defer/promise described here http://blog.mediumequalsmessage.com/promise-deferred-objects-in-javascript-pt1-theory-and-semantics

JS returning before AJAX call returning output? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to return AJAX response Text?
I'm calling a javascript method which in turn sends Ajax request and gives response.I'm getting the result in callback method like "success".
Here Ajax is returning some result, in the mean while javascript method returning result (something as undefined).
But it should return ajax result only.
The problem i was identified is, Javascript and Ajax are both concurrently executing.
How to stop them and first execut Ajax and it's result must send to function which returns the result.
Any idea is Highly Appreciated.. :)
By default, $.ajax (and anything that uses it, such as $.post) makes asynchronous requests. You can make the request synchronous by specifying async:false (see documentation). I don't recommend you use synchronous AJAX requests, though, as it degrades performance and leads to poor user experience. Instead, consider using a callback which is invoked in your success handler when the result is complete.
Here are two arbitrary and simple examples, where we have an anchor that we want to have the text replaced from the result of an AJAX call when clicked. Both do the same thing, but the second one is preferred because it keeps the browser responsive.
Synchronous:
function invokeAjaxSync() {
var text;
$.ajax({url: '/path/to/resource', async:false, success: function(result) {
text = result.toString();
}}); // will wait until this call is complete
return text;
}
$('a.example').click(function() {
$(this).text(invokeAjaxSync()); // works, but the browser will be unresponsive while waiting for a response.
});
Asynchronous (better):
function invokeAjaxAsync(callback) {
$.ajax({url:'/path/to/resource', success: function(result) {
callback(result);
}});
}
$('a.example').click(function() {
var $this = $(this);
invokeAjaxAsync(function(result) {
$this.text(result.toString());
}); // browser will remain responsive, but still update text when the AJAX call completes.
});

Categories

Resources