This question already has answers here:
How to make synchronous JSONP crossdomain call
(4 answers)
Closed 8 years ago.
I am having some issues with synchronous calls,
and can't seem to understand exactly what's going wrong.
When debugging the code, it fills up the songTracks array perfectly,
just until the return statement, where it is empty again.
Code sample:
function getAllSongIds(lijstId){
var songTracks = [];
$.ajax({
url: "http://somehost.com/lists/"+lijstId+"/editions/",
dataType: "jsonp",
async: false,
success: function(json){
for (i in json.editions) {
$.ajax({
url:"http://somehost.com/lists/"+lijstId+"/editions/"+json.editions[i].id,
dataType:"jsonp",
async: false,
success: function(json2){
for(j in json2.tracks){
if(songTracks.indexOf(json2.tracks[j].id) === -1){
songTracks.push(json2.tracks[j].id);
}
}
}
})
};
}
});
alert(songTracks);
return songTracks;
};
JSONP is always asynchronous. The async: false setting is simply ignored. From the documentation:
[...] If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation.
Why?
JSONP has actually nothing to do with Ajax. jQuery is just providing a single function to deal with both. JSONP is nothing else but appending a <script> element to the document. The browser will load these scripts asynchronously.
See How do I return the response from an asynchronous call? for possible (asynchronous) solutions.
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
Good evening guys,
I have the following requisition AJAX:
function getJson(url) {
var json;
$.ajax({
type: "POST",
url: url,
dataType: "json",
async: false,
success: function (data)
{
alert(data);
json= data;
}
});
return json;
}
When a execute, it shows a json on Chrome's network tab. But i can't manipulate using the variable data neither in an alert nor on return. There is something wrong with the code?
You are misunderstanding asynchronous functions. When JS runs that $.ajax, it doesn't wait for it to finish before continuing on with the code. So, when you return json; you are returning it before it is defined. You are going to have to refactor your code by using nested callbacks, promises, or async/await. This is a common problem that people new to asynchronous programming encounter and it can be very frustrating to learners.
I have seen a code for some chat system which says some thing like below to get the chat messages. I have seen that AJAX is asynchronous. setTimeout here is refreshing the chatlog periodically. So on the whole is it asynchronous communication? $.ajax is synchronous or asynchronous? what is its significance here????
http://net.tutsplus.com/tutorials/javascript-ajax/how-to-create-a-simple-web-based-chat-application/
Asynchrounous communication means the server has to send the data to client if there is any new data without the client bugging the server. Isn't it? Please give me a detailed explanation of what's going on below ....... Any better solution how chatlog can be updated automatically with jquery-ajax
if we are checking every x seconds and reloading the whole window again, what is the need to use $.ajax here? just making code complex .... what is the difference between using just php-sql request to the database and setimeout .... cost of the first case: the whole chat is reloaded over and over+ajax call, cost of the second case: whole chat is loaded over and over ... so i don't understand what is the benefit of using ajax according to performance .... in fact i see the later is better...... Isn't it???
function updateMsg()
{
$.ajax({
url:"db.php",
type:"POST",
success:function(data){
}
});
setTimeout("updateMsg()",7000);
}
You can use async param. async param determines: is request synchronous or asynchronous
$.ajax({
url:"db.php",
type:"POST",
async: true, // async: false
By default is async :
async (default: true) Type: Boolean By default, all requests are sent
asynchronously (i.e. this is set to true by default). If you need
synchronous requests, set this option to false. Cross-domain requests
and dataType: "jsonp" requests do not support synchronous operation.
Note that synchronous requests may temporarily lock the browser,
disabling any actions while the request is active. As of jQuery 1.8,
the use of async: false with jqXHR ($.Deferred) is deprecated; you
must use the success/error/complete callback options instead of the
corresponding methods of the jqXHR object such as jqXHR.done() or the
deprecated jqXHR.success().
function updateMsg() {
$.ajax({
url: "db.php",
type: "POST",
async: true, //or false
success: function (data) {}
});
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it posible to use ajax respone outside of it?
I've created the following JavaScript routine that goes to a WCF oData service and gets some data. In the success element I get the results into the results variable and alert them - I see that there are objects returned. When I run the second alert, outside of the ajax call and before returning the results, the results variable is "undefined".
Can anyone please tell me where I'm going wrong?
function retrieveJsonpODataSet(baseUrl, query)
{
var oDataUrl = baseUrl + "?$format=json&$callback=?";
var results;
$.ajax(
{
url: oDataUrl,
contentType: 'application/json; charset=utf-8',
type: 'GET',
dataType: 'jsonp',
async: false,
success:
function (data, textStatus, xhr)
{
results = data.d;
alert(results); // This shows the results
},
error:
function (xhr, textStatus, errorThrown)
{
alert("Query failed.\n\n" + oDataUrl + "\n\n" + errorThrown);
results = null;
}
});
alert(results); // This shows "undefined"
return results;
}
Please ignore the query parameter - I've not finished the routine yet.
EDIT
Initially I had no async:false in the ajax call. I've added that now but it doesn't fix the problem.
The ajax call is an asynchronous operation. It fires and your code does not stop at it. So results is returned which at that point is undefined. What you need to do is to pass callback to the function.
function retrieveJsonpODataSet(baseUrl, query, callback) {
/* some code */
$.ajax({
/* some settings */
success: function(res) {
/* some code */
callback(results);
}
});
}
Now you use it like this
retrieveJsonpODataSet(baseUrl, query, function(res) {
/* Hurray, I have result now in res variable! */
});
DO NOT USE async: false OPTION! It blocks ALL scripts untill the call finishes... and what if it does not finish at all?? You will be blocked forever.
EDIT
I've missed that the request is JSONP. In that case async: false won't even work (it does not work for cross-domain requests and JSONP). So you have to use callbacks anyway.
A fellow Richard!
This isn't a scope issue, but more of an execution one. Both the success and error options are event handlers, and run asynchronously (hence it being called AJAX). This essentially means that the alert(results) and return results can, and likely will, get executed before the success or error events are triggered.
Your ajax is async, so the alert executes before the ajax completes. You need to set the ajax call async property to false in order for script to halt the execution until ajax request is made & processed.
However, jQuery docs says:
async
Default: true
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active. As of jQuery 1.8, the use of async: false is deprecated.
AJAX request are sent, without the script waiting for a response, that's what Dave Newton means by A-synchronus, put the alert inside the success callback function, and you'll see what the actual response is.
alternatively, you can specify the async property, and set it to false, to force your script to wait for the response, before continuing.
I'm using jQuery $.getJSON(..) to get some json.
The passed value shows me "undefined".
Is there a way to do that?
getTopMenuJson : function(currentPage) {
if(currentPage == null) currentPage = 1;
var retJSON;
$.getJSON(
requestURLs.topMenuJson,
{
'ITEM_PER_PAGE' : TopMenuHandler.ITEM_PER_PAGE,
'CURRENT_PAGE' : currentPage
},
function(JSON) {
//alert(JSON); **<--This gives me result (Object)**
retJSON = JSON;
}
);
**alert(retJSON); //<!-- This doesn't, but Undefined**
},
It doesn't and it shouldn't as getJSON is internally doing an AJAX call, the first A in AJAX stands for Asynchronous, it simply means that the script execution won't wait until your success function is called.
You could instead use $.ajax and pass in async: false to one of its options to make sure that your script waits for the ajax call to be finished, but be aware that doing that would freeze the browser / tab until your AJAX call is finished.
$.ajax({
url: requestURLs.topMenuJson,
dataType: 'json',
data:
{
'ITEM_PER_PAGE' : TopMenuHandler.ITEM_PER_PAGE,
'CURRENT_PAGE' : currentPage
},
success: function(JSON) {
//alert(JSON); **<--This gives me result (Object)**
// this won't work without async:false
// as the execution of script won't wait until this function
// is finished
retJSON = JSON;
},
async: false
});
http://api.jquery.com/jQuery.ajax/
async Default: true By default, all requests are sent
asynchronously (i.e. this is set to true by default). If you need
synchronous requests, set this option to false. Cross-domain requests
and dataType: "jsonp" requests do not support synchronous operation.
Note that synchronous requests may temporarily lock the browser,
disabling any actions while the request is active.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
the question is fairly simple and technical:
var it_works = false;
$.post("some_file.php", '', function(data) {
it_works = true;
});
alert(it_works); # false (yes, that 'alert' has to be here and not inside $.post itself)
What I want to achieve is:
alert(it_works); # true
Is there a way to do that? If not can $.post() return a value to be applied to it_works?
What you expect is the synchronous (blocking) type request.
var it_works = false;
jQuery.ajax({
type: "POST",
url: 'some_file.php',
success: function (data) {
it_works = true;
},
async: false // <- this turns it into synchronous
});
// Execution is BLOCKED until request finishes.
// it_works is available
alert(it_works);
Requests are asynchronous (non-blocking) by default which means that the browser won't wait for them to be completed in order to continue its work. That's why your alert got wrong result.
Now, with jQuery.ajax you can optionally set the request to be synchronous, which means that the script will only continue to run after the request is finished.
The RECOMMENDED way, however, is to refactor your code so that the data would be passed to a callback function as soon as the request is finished. This is preferred because blocking execution means blocking the UI which is unacceptable. Do it this way:
$.post("some_file.php", '', function(data) {
iDependOnMyParameter(data);
});
function iDependOnMyParameter(param) {
// You should do your work here that depends on the result of the request!
alert(param)
}
// All code here should be INDEPENDENT of the result of your AJAX request
// ...
Asynchronous programming is slightly more complicated because the consequence
of making a request is encapsulated in a function instead of following the request statement. But the realtime behavior that the user experiences can be significantly
better because they will not see a sluggish server or sluggish network cause the
browser to act as though it had crashed. Synchronous programming is disrespectful
and should not be employed in applications which are used by people.
Douglas Crockford (YUI Blog)
AJAX stands for Asynchronous JavaScript and XML. Thus, the post to the server happens out-of-sync with the rest of the function. Try some code like this instead (it just breaks the shorthand $.post out into the longer $.ajax call and adds the async option).
var it_works = false;
$.ajax({
type: 'POST',
async: false,
url: "some_file.php",
data: "",
success: function() {it_works = true;}
});
alert(it_works);
Hope this helps!
It seems that your problem is simply a concurrency issue. The post function takes a callback argument to tell you when the post has been finished. You cannot make the alert in global scope like this and expect that the post has already been finished. You have to move it to the callback function.
The reason your code fails is because post() will start an asynchronous request to the server. What that means for you is that post() returns immediately, not after the request completes, like you are expecting.
What you need, then, is for the request to be synchronous and block the current thread until the request completes. Thus,
var it_works = false;
$.ajax({
url: 'some_file.php',
async: false, # makes request synchronous
success: function() {
it_works = true;
}
});
alert(it_works);