Difference between Synchronous and Asynchronous Ajax request - ajax

Other than that if there is some code after ajax call In asynchronous it executes first. In synchronous It executes one after the other in the code.

Synchronous ( async: false ) – Script stops and waits for the server to send back a reply before continuing. There are some situations where Synchronous Ajax is mandatory. In standard Web applications, the interaction between the customer and the server is synchronous. This means that one has to happen after the other.
Synchronous part:
$.ajax({
url: "file.php",
type: "POST",
async: false,
success: function(data) {
// write something awesome in response data part
}
});
Asynchronous Part:
$.ajax({
url: "file.php",
type: "POST",
async: true,
success: function(data) {
// write something awesome in response data part
}
});
Thats it. Basically people use asynchronous when they need to send request on completion of first request. Means, your requests will work one by one not all request will send at once. Instead of it, in synchronous ajax calls your all requests will be done synchronously.

Basically, Asynchronous requests do not really mind other codes if they have already executed or not. It only executes if it has already received the response from where you sent the request.
Ajax requests are Asynchronous by nature, but it can be set to Synchronous, thus, having the codes before it, execute first.
// Note: Synchronous ajax request already deprecated by jquery, it's better to use promises.

Synchronous Ajax request: It blocks event loop, meaning you/browser cannot do other activities (clicking a button, loading images etc )
Asynchronous Ajax request: It doesn't block event loop and able to do other activities while ajax is processing.
Event loop: Mechanism in javascript to achieve asynchronous operations. For details you can google it.

That's right.
Examples for Javascript:
var xhr = new XMLHttpRequest();
var button = document.getElementById('button');
xhr.open('GET', '/', true);
xhr.send(); // (1)
xhr.onreadystatechange = function() { // (3)
if (xhr.readyState != 4) return;
button.innerHTML = 'Ready!';
if (xhr.status != 200) {
alert(xhr.status + ': ' + xhr.statusText);
} else {
alert(xhr.responseText);
}
}
button.innerHTML = 'Loading...'; // (2)
button.disabled = true;
If there is third argument in xhr.open() and it equals true, then request will be asynchronous. It means that after call xhr.send() the code at (1) doesn't «hang», but still executes, the string (2) executes, and result of xhr request obtains after state-change event (3).
I slightly changed the code example from this article:
https://javascript.info/xmlhttprequest

<h2>Synchronous Request</h2>
<p id="demo"></p>
<script>
var xmlhttp = new XMLHttpRequest();
alert("after creating XMLHttpRequest ");
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
alert("In function");
document.getElementById("demo").innerHTML = "Name from JSON Data : " + myObj.name;
}
};
xmlhttp.open("GET", "emp.json", false);//Synchronous
xmlhttp.send();
alert("after send");
</script>
For better understanding I used alert to know how synchronous and asynchronous requests takes place,set as true and see

Related

Chain multiple POST requests together using AJAX and jQuery

I received a suggestion from a prior question that I need to amend my code chain a series of POST requests together, but I don't have any idea how to accomplish this. Specifically, the advice I was given was to:
fire off a post, have its success handler fire off the next post,
etc... and then when all the posts are done, the final post's success
handler fires off the get
This strategy makes sense to me but I do not know how to implement. I am trying to prevent the call to GET before all of the calls to POST have completed. Currently, I have implemented $.when.apply to delay the sending of GET. Here is the code for that:
function(){
$.when.apply(undefined, InsertTheAPPs()).done(function () {
$.ajax({
url: sURL + "fileappeal/send_apps_email",
success: function() {
var m = $.msg("my message",
{header:'my header', live:10000});
setTimeout(function(){
if(m)m.setBody('...my other message.');
},3000);
setTimeout(function(){
if(m)m.close(function(){
window.location.replace(sURL+'client/view');
});
},6000);
$('#ajaxShield').fadeOut(1000);},
error: function(){
$.msg("error message",
{header:'error header', live:10000});
}
});
});
}
Here is the code for the jQuery $.each loop. This is the code that needs to not only begin, but must end before the ajax call to fileappeal/send_apps_email above:
function InsertTheAPPs(){
$('input[name=c_maybe].c_box').each(function(){
var jqxhrs = [];
if($(this).prop('checked')){
var rn = $(this).prop('value');
jqxhrs.push(
$.ajax({
url: sURL + 'fileappeal/insert_app',
type:"POST",
dataType: 'text',
data: {'rn': rn},
error: function(data) {console.log('Error:'+rn+'_'+data);}
})
)
return jqxhrs;
}
});
}
Could someone demonstrate how I can modify the code above to implement the strategy of chaining together the multiple POST calls?
Don't return from .each. It doesn't work that way. Instead do this:
var jqxhrs = [];
$(...).each(...
});
return jqxhrs;
Nothing is assigned to the return value of .each, which you can't get anyway. Returning from each allows it to be used like break/continue, which doesn't make sense in your context.
Moreover, the var jqxhrs inside of the each loop causes a new variable to be declared in that context on each iteration of the loop.

Javascript Mootools event stop

well,i have this script that i have set up that on submit requests php file that is used to validate my input values...i have set up that when it is not validated the correct way to echo it is not validated,now i want in my request when i get response and it is the error response to stop the submit..here is the script,it does send the request and returns response but it doesnt stop the submit...
i have made it like this but now i need to pop a confirm message when it is all done,i want to stop the form from executing when message pops up and if the user clicks yes to continue with the form...i tried it like this with fireEvent but it wont work...help guys!
window.addEvent('domready', function(){
var form=document.adminForm;
form.addEvent('submit', function(e){
var success = false;
var dataString="date=" + document.getElementById("date").value + "&start=" + document.getElementById("start").value + "&end=" + document.getElementById("end").value;
var requestData = new Request ({
url: '/provjera.php',
method:'POST',
async:false,
data:dataString,
onComplete: function(responseText){
var requestData2 = new Request({
url:'/posalji.php',
method:'POST',
data:dataString,
onComplete:function(responseText){
}
});
requestData2.send();
success= responseText == 'NO ERROR';
if(responseText == 'NO ERROR'){
}else{
alert("FAIL");
}
}
});
requestData.send();
if(success){
var result=confirm("Are you sure!?");
e.stop();
if(result){
form.fireEvent("submit");
}
}else{
e.stop();
}
});
});
This won't work, it breaks the asynchronous nature of XHR (it's *A*JAX, heh).
The way it works is this:
[form]
[submit event]
\->[function]->[xhr]->[onComplete function much later]->[e.stop() not applicable]
\->[function continues and terminates]
By the time the onComplete arrives and calls .stop(), the parent function execution has exited and failed to stop the event, it has already bubbled... XHR is non-blocking!
you have 2 patterns you can do to work around that:
1. always stop event, do something extra in onComplete
essentially, whatever the XHR passes to your onComplete can let you determine the success/failure of your operation and you can call another function, fire an event or do what you need to do (eg, transition page or display validation errors on screen or whtever).
2. use sync AJAX (anti-pattern)
you can actually make your XHR blocking if you wanted to so that in this execution context you can set a variable or stop the event from the onComplete - do so by passing async: false to your Request constructor options.
I would definitely not recommend 2 unless you are doing something like username availability checker onBlur/onChange that needs to block the thread before they submit. And even then, you can do it gracefully w/o this.
edit as per request, here is an example: http://jsfiddle.net/dimitar/du5s4/
var form = document.id('adminForm');
form.addEvent('submit', function (e) {
var success = false;
// simulate a server response of two types.
this.getElement('input[name=html]').set('value', ['success','error'].getRandom());
var requestData = new Request({
url: '/echo/html/',
method: 'post',
async: false,
data: this,
onComplete: function (responseText) {
// if server returned success, don't stop the event.
success = this.response.text == 'success';
console.log(success);
}
}).send();
success || e.stop();
});
this has been tailored for the jsfiddle api for ajax testing but you get the idea. since you evalResponse, your response can also set variables - though I don't remember what the scope of evluation will be - it may be the global object and not the inner scope of the submit function.
once again, this is totally wrong, use sparringly. you need to change over to a proper event based setup.
http://jsfiddle.net/dimitar/du5s4/2/ - same thing but w/o the async hack.
var form = document.id('adminForm');
form.addEvent('submit', function (e) {
e && e.stop && e.stop();
var self = this;
// simulate a server response of two types.
this.getElement('input[name=html]').set('value', ['success','error'].getRandom());
var requestData = new Request({
url: '/echo/html/',
method: 'post',
data: this,
onComplete: function (responseText) {
// if server returned success,
// call something like form.submit();
this.response.text == 'success' && self.submit();
console.log(this.response.text);
}
}).send();
});

First ajax call on Phonegap + Zepto returns undefined even after device ready

I'm doing a jsonp call in my mobile app at startup to connect to my server. I'm using Phonegap 2.1 and Zepto 1.0-rc1. At the bottom of my html page, I do the init stuff on DOM ready.
<script type="text/javascript">
if (!$) {$ = Zepto};
$(init);
document.addEventListener('deviceready', Perksea.deviceReady);
</script>
...
function init() {
var router = new Backbone.Router();
...
}
function deviceReady() {
isConnected();
isConnected();
}
function isConnected() {
$.ajaxJSONP({
url: 'http://localhost/isconnected',
success: function(response) {
console.log('response is ' + response);
}
});
}
The first JSONP call will print "response is undefined" but the second JSONP call works. I've even tried putting the JSONP call in a setTimeout(isConnected, 5000) with the same result. Have already checked that the url is correct etc.
Has anyone seen something like this?
Thanks
Steve
since you are getting into the "success" callback function on the first call (where response is undefined), are you sure that your server is properly responding to the first call? Sounds like it is returning a 200 response, but with no data for that first call.
You can try adding an 'error' callback to see if that provides anything useful as well
$.ajaxJSONP({
url: 'http://localhost/isconnected',
success: function(response) {
console.log('response is ' + response);
}
error: function(response) {
console.log('error is ' + response);
}
});
Finally, because AJAX is Asynchronous, your 2 calls to isConnected() are going to fire one immediately after the other, not waiting for the first to respond. I'm curious what it looks like on the server side (see above).

Multiple AJAX calls on page load

I'm attempting to pull two separate things from outside sources to put onto an HTML page I'm creating. I have a successful AJAX function to pull the most recent video from a particular Youtube channel by parsing through the XML/RSS feed for that channel. I receive this feed through an AJAX call.
I'd also like to get the most recent blog post from a Blogger account. The code for parsing the feed to get the most recent entry shouldn't be difficult, but I'm having trouble with simultaneous AJAX calls. I read somewhere that it can only handle one at a time? I'm weary about queuing them because I don't want to the content on the page to load in steps. I'd rather it all just get fetched simultaneously. How might I go about doing this?
Here is my current script:
<script type="text/javascript" charset="utf-8">
$(function() {
$.ajax({
type: "GET",
url: "http://gdata.youtube.com/feeds/base/users/devinsupertramp/uploads?orderby=updated&alt=rss&client=ytapi-youtube-rss-redirect&v=2",
dataType: "xml",
success: parseXml
});
});
function parseXml(xml) {
$(xml).find("item:first").each(
function() {
var tmp = $(this).find("link:first").text();
tmp = tmp.replace("http://www.youtube.com/watch?v=", "");
tmp = tmp.replace("&feature=youtube_gdata", "");
var tmp2 = "http://www.youtube.com/embed/" + tmp + "?autoplay=1&controls=0&rel=0&showinfo=0&autohide=1";
var iframe = $("#ytplayer");
$(iframe).attr('src', tmp2);
}
);
}
</script>
I read somewhere that it can only handle one at a time?
Either you misunderstood what the person was trying to say or they were incorrect. Javascript doesn't run any functions concurrently so someone with poor English might reword that as "can only handle one at a time" but that doesn't mean you can't make multiple AJAX calls. jQuery is smart and will do what it needs to do to make sure both calls are executed eventually.
If you'd like all the content to be loaded simultaneously the sad fact is you can't. However you can make it appear that way to the user by declaring a flag that is set by the success method of each call. Then just keep the content hidden until both flags have been set.
EDIT:
Here's a very simplistic approach to make it appear that they are fetched simultaneously:
<script type="text/javascript" charset="utf-8">
var youtubComplete = false;
var otherComplete = false;
$(function() {
$.ajax({
type: "GET",
url: "http://gdata.youtube.com/feeds/base/users/devinsupertramp/uploads?orderby=updated&alt=rss&client=ytapi-youtube-rss-redirect&v=2",
dataType: "xml",
success: parseXml
});
$.ajax({
type: "GET",
url: "http://someotherdata.com/",
dataType: "xml",
success: function() { otherComplete = true; checkFinished(); }
});
});
function parseXml(xml) {
$(xml).find("item:first").each(
function() {
var tmp = $(this).find("link:first").text();
tmp = tmp.replace("http://www.youtube.com/watch?v=", "");
tmp = tmp.replace("&feature=youtube_gdata", "");
var tmp2 = "http://www.youtube.com/embed/" + tmp + "?autoplay=1&controls=0&rel=0&showinfo=0&autohide=1";
var iframe = $("#ytplayer");
$(iframe).attr('src', tmp2);
}
);
youtubeComplete = true;
checkFinished();
}
function checkFinished()
{
if(!youtubeComplete || !otherComplete) return;
// ... Unhide your content.
}
</script>
The browser will support multiple outbound calls but there is a cap per domain. Take a look at this related Q/A How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?.
There are several good libraries for doing request scheduling including chaining and parallelizing AJAX calls. One good library is https://github.com/kriskowal/q, which provides async promises framework to enable arbitrarily complicated chaining of AJAX requests. Q minified is about 3.3KB.
// The jQuery.ajax function returns a 'then' able
Q.when($.ajax(url, {dataType: "xml"}))
.then(function (data) {
var parsedXML = parseXML(data)
...
// some other ajax call
var urls = [Q.when($.ajax(url2, {data: {user: data.userId}})),
Q.when($.ajax(url3, {data: {user: data.userId}}))];
// run in parallel
return Q.all(urls)
})
.then(function (data) {
// data retrieved from url2, url2
})

jQuery.ajax() sequential calls

Hey. I need some help with jQuery Ajax calls. In javascript I have to generste ajax calls to the controller, which retrieves a value from the model. I am then checking the value that is returned and making further ajax calls if necessary, say if the value reaches a particular threshold I can stop the ajax calls.
This requires ajax calls that need to be processes one after the other. I tried using async:false, but it freezes up the browser and any jQuery changes i make at the frontend are not reflected. Is there any way around this??
Thanks in advance.
You should make the next ajax call after the first one has finished like this for example:
function getResult(value) {
$.ajax({
url: 'server/url',
data: { value: value },
success: function(data) {
getResult(data.newValue);
}
});
}
I used array of steps and callback function to continue executing where async started. Works perfect for me.
var tasks = [];
for(i=0;i<20;i++){
tasks.push(i); //can be replaced with list of steps, url and so on
}
var current = 0;
function doAjax(callback) {
//check to make sure there are more requests to make
if (current < tasks.length -1 ) {
var uploadURL ="http://localhost/someSequentialToDo";
//and
var myData = tasks[current];
current++;
//make the AJAX request with the given data
$.ajax({
type: 'GET',
url : uploadURL,
data: {index: current},
dataType : 'json',
success : function (serverResponse) {
doAjax(callback);
}
});
}
else
{
callback();
console.log("this is end");
}
}
function sth(){
var datum = Date();
doAjax( function(){
console.log(datum); //displays time when ajax started
console.log(Date()); //when ajax finished
});
}
console.log("start");
sth();
In the success callback function, just make another $.ajax request if necessary. (Setting async: false causes the browser to run the request as the same thread as everything else; that's why it freezes up.)
Use a callback function, there are two: success and error.
From the jQuery ajax page:
$.ajax({
url: "test.html",
context: document.body,
success: function(){
// Do processing, call function for next ajax
}
});
A (very) simplified example:
function doAjax() {
// get url and parameters
var myurl = /* somethingsomething */;
$.ajax({
url: myurl,
context: document.body,
success: function(data){
if(data < threshold) {
doAjax();
}
}
});
}
Try using $.when() (available since 1.5) you can have a single callback that triggers once all calls are made, its cleaner and much more elegant. It ends up looking something like this:
$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1, a2){
// a1 and a2 are arguments resolved for the page1 and page2 ajax requests, respectively
var jqXHR = a1[2]; /* arguments are [ "success", statusText, jqXHR ] */
alert( jqXHR.responseText )
});

Resources