Ajax Call Sequence in a function - javascript

I have a little question. say i have a js function
$(function() {
$(".button").click(function(){
var id=$(this).attr('id');
var dataString = 'id='+ id ;
$.ajax({
type: "POST",
url: "download_number.php",
data: dataString,
cache: false,
success: function(html)
{
$("#div_"+id).html(html);
} });
window.open('File_download.php?file_id='+id, '_blank' );
});
as you can see window.open call is after $.ajax call
Does it guaratee that $.ajax call will get executed every time before the page reloads and if no then
shouldn't we declare window.open in success function?
In my opinion when there is slow response from server the page will reload first and it may happen that $.ajax call will be interrupted by window.open function
but i get a downvote for the same reason here stackoverflow.com/questions/12908138/how-to-get-the-id-or-name-of-related-file/
And Thanks for making my belief stronger

In your example, the window.open function will always (!) be called before the success callback function given to the ajax call. Ajax traffic is always asynchronous, whereas the window.open function resides in the synchronous JS <script> tag.
Since JavaScript is single-threaded, all synchronous statements will always be executed before any asynchronous functionality like ajax setTimeout animate etc.
$.ajax({
type: "POST",
url: "download_number.php",
data: dataString,
cache: false,
success: function(html) { // asynchronous functionality
$("#div_"+id).html(html);
}
});
// within synchronous script statements
window.open('File_download.php', '_blank' );

Yes, Ajax is asynchronous so you will open that window right after you started the XHR process. To download the processed data, open the new window from the success callback. Yet I'm not sure what you mean by "before the page reloads" - there is no code which does that.
Also I don't know how your server behaves, the file_download.php seems to be independent from your ajax call. Shouldn't you pass the download_number you received via ajax in there?

Related

Load HTML content synchronously

I need to load HTML in a div.
$("#content").load("content.html");
$("#myText").html("Prasath");
After that I need to update some text in a div(id='myText') which is available in "content.html". "content.html" contains huge data, so it takes some time to load. Before that this line is executed:
$("#myText").html("Prasath");
How to load HTML content synchronously from JavaScript/jQuery ?
I don't want to do this from call back option in load.
You can't load it synchronously but you can quite easily do the next task in the load() callback. For example:
$("#content").load("content.html", function() {
$("#myText").html("Prasath");
});
$("#content").load("content.html", function(data){
// this will execute after load is fired.
});
Use a callback.
EDIT: If you really want to make synchronous request, you can use the following code. However, you'll get a warning in console as I mentioned in the comment earlier:
var data = $.ajax({
type: "GET",
url: "content.html",
async: false
}).responseText;
// this code waits for the above ajax request.
Please have a look on the JQuery documentation about load().
You can pass callback function to load()
For example:
$("#content").load("content.html", function(){
$("#myText").html("Prasath");
});
EDIT: There is no way to make load() to load content synchronously. A workaround solution is that you can define a Jquery function that use ajax() to send synchronous request to target url and then set the response content to destinate div.
$(function(){
$.fn.extend({
syncLoad: function (url) {
var result = $.ajax({
url: url,
async: false,
type: "GET"
}).responseText;
$(this).html(result);
}
});
$("#content").syncLoad("/echo/js/?js=hello%20world!");
});
JS Fiddle: https://jsfiddle.net/1v8fmb8b/

jQuery Get Function change to make asynchronous

I have some old code which I've now being asked to make asynchronous.
It's basically a jQuery GET function ... like this:
jQuery.get("my url", function(data){
//code here
});
How can I make this asynchronous?
By default jQuery.get is an asynchronous call , to make it synchronous you have to set it
jQuery.ajaxSetup({async:false});
Perhaps you mistyped your question—ajax calls are asynchronous by default, but here is how you would make it synchronous.
The best way would be to use the long-form ajax request (for which jQuery.get() is shorthand).
It would look like the following
jQuery.ajax({
method: "GET",
url: "my url",
async: false,
data: data,
success: function(data){},
});
The reason why jQuery.ajaxSetup({async:false}); is bad form is because it makes every ajax call synchronous, not just the individual call you want to change.

Is there a way to synchronize ajax calls

It may be a trivial question, but I am wondering if there is way to somehow know when the last ajax call gets completed. So lets say I have 3 asynchronous ajax calls
$.ajax({
type: "GET",
datatype: "json",
url: <my service url 1>
})
.done(function() {
// handler
});
$.ajax({
type: "GET",
datatype: "json",
url: <my service url 2>
})
.done(function() {
// handler
});
$.ajax({
type: "GET",
datatype: "json",
url: <my service url 3>
})
.done(function() {
// handler
});
I want to show a progress bar when the first call starts and hide it when the last one finish. The issue is that even though I call them in sequence, because calls are asynchronous, I don't know how to tell when all calls finish. I could nest them one inside another, but then as far as I understand it will take much longer as one will have to wait for another to finish. Is there a way to sync it somehow?
I used to have the same need. If you can use jQuery, have a look there : http://lostechies.com/joshuaflanagan/2011/10/20/coordinating-multiple-ajax-requests-with-jquery-when/
Otherwise, you can pass a simple callback function through your AJAX call that comes back in your progress indicator update at the end of each async treatment.
Already answered, but consider using global events instead -
AjaxStart - Triggered when any ajax call starts
AjaxStop - Triggered when all ajax calls are finished
Example -
$( document ).ajaxStart(function() {
$( "#progressBar" ).show();
});
$( document ).ajaxStop(function() {
$( "#progressBar" ).hide();
});
But you will need to make sure that the second call begins before the first call is complete or atleast it should be triggered immediately after the first one completes.

javascript critical sections or semaphore problem

function myobj(){
var gup=this;
this.lastindex=-1;
this.criticalSectionInTimer=0;
this.updateTimer;
this.start = function(l){
if((typeof this.updateTimer)=="number"){
clearInterval ( this.updateTimer );
}
this.updateTimer=setInterval(function() {gup.getMessages();} , 30);
}
this.stop= function(){
if((typeof this.updateTimer)=="number"){
clearInterval ( this.updateTimer );
}
}
this.addUpdate(i){
//some code
}
this.rrrrnr=0;
this.getMessages = function (){
if(this.criticalSection==0){
this.criticalSection=1;
this.rrrrnr++;
console.log("in critical section"+this.rrrrnr);
var url="getmessages.php?lastindex="+this.lastindex;
$.getJSON(url,
function(data){
gup.lastindex=data.lastindex;
$.each(data.updates, function(i,item){
gup.addUpdate(item);
});
}
);
console.log("out critical section"+this.rrrrnr);
this.criticalSection=0;
}
}
}
var m= new myobj();
myobj.start();
I have the code from above. I have a main loop which makes updates at a given time interval. The problem is i have realized that it is getting in the "critical section" which I have delimited by the variable this.criticalSection .
From firebug i get the messages "in critical section" + index and "out critical section" +index in the right order but the ajax request is still being processed. But I get request with the same index and i really don't know where to look for the problem.
Are there any buildin features for semaphores or critical sections in javascript?
There aren't semaphores or critical sections because JavaScript is single-threaded. The ajax call you make is asynchronous, so it kicks off the request and then happily keeps going and leaving your critical section. As others have mentioned, a simple solution is to make the request synchronous, but this defeats the purpose of ajax.
Looking at your code, it seems like you are trying to get updates at regular intervals. If this is the case, why not schedule the next update in the callback of the ajax request?
this.getMessages = function (){
var url="getmessages.php?lastindex="+this.lastindex;
$.getJSON(url,
function(data){
gup.lastindex=data.lastindex;
$.each(data.updates, function(i,item){
gup.addUpdate(item);
});
gup.updateTimer=setTimeout(gup.getMessages, 30);
}
);
}
This would remove the need for semaphores, and is more in line with the event-driven nature of JavaScript. The downside is the updates are not done at exact intervals. Also, 30 milliseconds seems an extremely short interval.
jQuery send AJAX Async by default. Insted of doing getJSON try:
$.ajax({
dataType: 'json',
url: url,
type: 'GET',
async: false,
success: function(data){
gup.lastindex=data.lastindex;
$.each(data.updates, function(i,item){
gup.addUpdate(item);
});
});
The proble is fairly simple.
You are using AJAX, which, by definition, is asynchronous. That means, you execute $.getJSON, and the js will continue and exit the critical section while the request is being processed. Therefore, several calls to getMessages can be performed before the first requests completes.
It seems that you intend such a getJSON call NOT not be async, and be blocked within the critical section until it ends. To do so, you must set the async property to false, something in the lines of:
$.ajax({
dataType: 'json',
url: "getmessages.php?lastindex="+this.lastindex,
type: 'GET',
async: false,
success: function(data){
gup.lastindex=data.lastindex;
$.each(data.updates, function(i,item){
gup.addUpdate(item);
});
});

Make sure ajax function finishes before 2nd non-ajax function fires

Similar to the question I just asked,
If I call an ajax function in jQuery and then a non ajax function how can I prevent the non-ajax function from firing until after the first ajax callback function has completed. Will declaring async: false in the first ajax function be enough?
If you're talking about this:
$.ajax({...});
someFunction();
where someFunction() won't occur until the AJAX call completes then you have three options:
Make the AJAX call async: false. Don't do this. It'll make your page unresponsive;
Put someFunction() in the complete/success/error callbacks of the AJAX call. This is the recommended approach; or
Use aplugin to manage a request queue eg Ajax Queue.
The first A in AJAX stands for "asynchronous". You just need to get used to the fact that these calls are asynchronous and stop trying to force a synchronous programming model on top of them. Adapt to the new programming model.
jQuery AJAX functions let you provide a callback that is only called after the request is finished. Call your non-ajax function as part of that callback.
You can use callback functions like this:
$("#btnSample").on("click", function (e) {
$.ajax({
url: 'some_url',
type: "GET",
async: true,
cache: false,
dataType: "JSON",
data: {
"p1": v1,
"p2": v2
},
success: function(result) {
//call you second function here!
}
}
});
});

Categories

Resources