Related
I have some async ajax requests
$.ajax({
url: 'first.php',
async: true,
success: function (data) {
//do stuff
}
});
$.ajax({
url: 'second.php',
async: true,
success: function (data) {
//do stuff
}
});
...
$.ajax({
url: 'nth.php',
async: true,
success: function (data) {
//do stuff
}
});
I want to run console.log() when every request is done.
I usually write this code:
$.ajax({
url: 'first.php',
async: true,
success: function (data) {
$.ajax({
url: 'second.php',
async: true,
success: function (data) {
//till the last ajax
}
});
}
});
However someone suggest Promise.all([]).
If I had to run, lets say, 4 ajax requests, which method would be the best/quickest?
Use Promise.all().
var promises = [];
promises.push(new Promise(done=>{
$.ajax({
url: 'first.php',
async: true,
success: done
});
}));
promises.push(new Promise(done=>{
$.ajax({
url: 'second.php',
async: true,
success: done
});
}));
promises.push(new Promise(done=>{
$.ajax({
url: 'nth.php',
async: true,
success: done
});
}));
Promise.all(promises).then(()=>{
console.log("All ajax completed.");
});
The official jQuery documentation states that:
The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise (see Deferred object for more information).
jQuery.when():
Provides a way to execute callback functions based on zero or more Thenable objects, usually Deferred objects that represent asynchronous events.
So you can do something like:
jQuery.when(
$.ajax({
url: 'first.php',
async: true,
success: function (data) {
//do stuff
}
}),
$.ajax({
url: 'second.php',
async: true,
success: function (data) {
//do stuff
}
}),
...,
$.ajax({
url: 'nth.php',
async: true,
success: function (data) {
//do stuff
}
})
).then(function() {console.log(...);});
how can I call ajax request or any function simple in new thread?
I know about async: false but my code has this structure:
1.user click on some item, and this fire click event
2.in event I call this function
var myData= {};
$.ajax({
type: "GET",
url: "...",
contentType: "application/json; charset=utf-8",
async: false,
cache: false,
dataType: "json",
success: function (s0) {
myData.s0= s0;
$.ajax({
type: "GET",
url: "sss",
contentType: "application/json; charset=utf-8",
async: false,
cache: false,
dataType: "json",
success: function (s1) {
myData.s1 = s1;
$.ajax({
type: "GET",
url: "...",
contentType: "application/json; charset=utf-8",
async: false,
cache: false,
dataType: "json",
success: function (s2) {
myData.s2= s2;
}
});
}
});
}
});
// I need call this function when all ajax are done.
myFunc(myData);
My current code works but causes the web freezes until data are not downloaded beaouse I have asyn: false but I do not know how to solve it asynchronously
Optimal solution for me is call this freezing and display loading gif until done.
Well there is no fix for UI freeze during a synchronous AJAX so you might want to try web workers but it has its own caveat .I would suggest you to use jquery promise so that you don't need to define separate success ,error callbacks .A promise is guaranteed to yield so at the end of chain either you will have values in myData or not but it won't hangup forever
//show loader
$.ajax({
type: "GET",
url: "...",
contentType: "application/json; charset=utf-8",
async: false,
cache: false,
dataType: "json",
}).then(function( s0, textStatus, jqXHR ){
myData.s0= s0;
return $.ajax( {
type: "GET",
url: "sss",
async: false,
cache: false,
dataType: "json"} );
}).then(function( s1, textStatus, jqXHR ) {
myData.s1 = s1;
$.ajax( {
type: "GET",
url: "...",
async: false,
cache: false,
dataType: "json"});
}).then(function( s2, textStatus, jqXHR ) {
myData.s2= s2;
//hide loader
})
Read more
Change async:false to async:true on all ajax calls, show loading gif at the start of your function where you initialize myData and call the function you want to call when all data is loaded in the success function on the last ajax call (just after myData.s2 = s2)
In the following javascript code, I am sending two Ajax request at the same time.
After analysis using Firebug, I came to unusual conclusion that :
"which ever (Ajax) response is coming first is printing last".
Problem 2: if I assign the Ajax url destination to a random string (say "abcd") [which don't exist] then total number of ajax call will be increased to 3?
$(document).ready(function(e) {
$("form[ajax=true]").submit(function(e) {
e.preventDefault();
var form_data = $(this).serialize();
var form_url = $(this).attr("action");
var form_method = $(this).attr("method").toUpperCase();
$("#loadingimg").show();
$.ajax({
url: form_url,
type: form_method,
data: form_data,
cache: false,
success: function(returnhtml){
alert ("a");
// $("#result").html(returnhtml);
// $("#loadingimg").hide();
}
});
$.ajax({
url: form_url,
type: form_method,
data: form_data,
cache: false,
success: function(returnhtml){
// $("#duplicate").html(returnhtml);
// $("#loadingimg").hide();
alert("b");
}
});
});
});
Please refer the following Fiddle.
Gaurav, you have an error, at the end of the 1st $.ajax it must end as ), and 2nd as ).
You can't end with ;
var result1;
var result2;
$.when(
$.ajax({ // First Request
url: form_url,
type: form_method,
data: form_data,
cache: false,
success: function(returnhtml){
result1 = returnhtml;
}
}),
$.ajax({ //Seconds Request
url: form_url,
type: form_method,
data: form_data,
cache: false,
success: function(returnhtml){
result2 = returnhtml;
}
})
).then(function() {
$('#result1').html(result1);
$('#result2').html(result2);
});
I'm not sure I completely understand, but I will try to give you some information. Like David said It may seem that the first request is the last one responding, but that will vary under many circumstances. There are different ways you could do this to control the outcome or order of the requests.
1) Upon success of the first request you could initiate the second request. I don't recommend this for speed purposes as your requests aren't running in parallel.
$.ajax({ // First Request
url: form_url,
type: form_method,
data: form_data,
cache: false,
success: function(returnhtml){
$.ajax({ //Seconds Request
url: form_url,
type: form_method,
data: form_data,
cache: false,
success: function(returnhtml){
// $("#duplicate").html(returnhtml);
// $("#loadingimg").hide();
alert("b");
}
});
alert ("a");
// $("#result").html(returnhtml);
// $("#loadingimg").hide();
}
});
2) If you need to have both requests responses at the same time, the preferred method would likely be jQuery deferred. This will make both requests run in parallel, and once both responses are received you can proceed as you would have.
Something Like this:
var result1;
var result2;
$.when(
$.ajax({ // First Request
url: form_url,
type: form_method,
data: form_data,
cache: false,
success: function(returnhtml){
result1 = returnhtml;
}
});
$.ajax({ //Seconds Request
url: form_url,
type: form_method,
data: form_data,
cache: false,
success: function(returnhtml){
result2 = returnhtml;
}
});
).then(function() {
$('#result1').html(result1);
$('#result2').html(result2);
});
Check out:
https://api.jquery.com/jQuery.when/
http://api.jquery.com/deferred.then/
https://api.jquery.com/deferred.done/
I hope this helps!
Or use server_response in your code. The script begin with condition:
if (recherche1.length>1) {
$.ajax({ // First Request
type :"GET",
url : "result.php",
data: data,
cache: false,
success: function(server_response){
$('.price1').html(server_response).show();
}
}),
$.ajax({ //Seconds Request
type :"GET",
url : "result2.php",
data: data,
cache: false,
success: function(server_response){
$('.price2').html(server_response).show();
}
});
}
var result1;
var result2;
$.when(
$.ajax({ // First Request
url: form_url,
type: form_method,
data: form_data,
cache: false,
success: function(returnhtml){
result1 = returnhtml;
}
});
$.ajax({ //Seconds Request
url: form_url,
type: form_method,
data: form_data,
cache: false,
success: function(returnhtml){
result2 = returnhtml;
}
});
).then(function() {
$('#result1').html(result1);
$('#result2').html(result2);
});
I have two ajax call that cannot be done in one call. When the first ajax call starts the second ajax call can start immediately or whenever the user presses a send button. If the second ajax call starts he has to wait for the response of the first ajax call because he needs data from it.
How can I achieve that the second ajax call sends his request only after the first ajax call's response has been arrived?
Is there another way than setTimeout?
Can I register a listener for ajax call 2 on ajax call 1 somehow?
My code would be:
var xhrUploadComplete = false;
// ajax call 1
$.ajax({
url: url,
type: "POST",
data: formdata,
processData: false,
contentType: false,
complete: function(response) {
var returnedResponse = JSON.parse(response.responseText);
xhrUploadComplete = true;
}
});
// ajax call 2
if (xhrUploadComplete) {
$.ajax({
url: url2,
type: "POST",
data: formdata2,
processData: false,
contentType: false,
complete: function(response) {
...
}
});
}
Edit: The second ajax call cannot be posted in done() or complete() of the first call, because it depends on the users choice to send the final form. The purpose of this two step process is to send an image to the server just after the user had inserted it to an input type=file.
Edit: In know that I cannot the the if(..) because this is an async call. I wrote it to make clear what I need to do. I think I need something like a future in Java.
xhrUploadComplete will be set to true asynchronously (in the future, when the request has finished) so your if-condition (that is evaluated right after the request is started) will never be fulfilled. You cannot simply return (or set) a value from an ajax call. Instead, move the code that waits for the results into the handler that would have set/returned the variable:
$.ajax({
url: url,
type: "POST",
data: formdata,
processData: false,
contentType: false,
complete: function(response) {
var returnedResponse = JSON.parse(response.responseText);
$.ajax({
url: url2,
type: "POST",
data: formdata2,
processData: false,
contentType: false,
complete: function(response) {
…
}
});
}
});
With the Promise pattern you can compose those even more elegantly:
$.ajax({
url: url,
type: "POST",
data: formdata,
processData: false,
contentType: false
}).then(function(response) {
var returnedResponse = JSON.parse(response.responseText);
return $.ajax({
url: url2,
type: "POST",
data: formdata2,
processData: false,
contentType: false
});
}).done(function(response) {
// result of the last request
…
}, function(error) {
// either of them failed
});
Maybe you need also need this:
var ajax1 = $.ajax({
url: url, …
}).then(function(response) {
return JSON.parse(response.responseText);
});
$(user).on("decision", function(e) { // whatever :-)
// as soon as ajax1 will be or has already finished
ajax1.then(function(response1) {
// schedule ajax2
return $.ajax({
url: url2, …
})
}).done(function(response) {
// result of the last request
…
}, function(error) {
// either of them failed
});
});
I'm trying to show a div with gif animation inside when a button click via javascript call. But the problem is, it's working fine in firefox only. In IE and Chrome, the animation won't show up. I've tried debugging with alert("stop"); before and after the animation and it's indeed working, but after I removed the alert, it won't work anymore. Any suggestion please?
Here's the snippet for the TestPage.aspx:
<div id="animationDiv" style="display: none;">
<img src="loading.gif" />
</div>
...
<div>
<asp:Button ID="testButton" runat="server" Text="Test AJAX" OnClientClick="return testButtonClick();" />
</div>
...
<script type="text/javascript">
<!--
var docWidth, docHeight;
function testButtonClick() {
var o_animationDiv = $("#animationDiv");
o_animationDiv.width(docWidth);
o_animationDiv.height(docHeight);
o_animationDiv.show();
$.ajax({
type: "Post",
url: "TestPage.aspx/TestAjax",
async: false,
cache: false,
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: testAjaxSuccess,
error: testAjaxError
});
function testAjaxSuccess(data, status, xhr) {
// do something here
};
function testAjaxError(xhr, status, error) {
// do something here
};
o_animationDiv.hide();
return false;
};
$(document).ready(function () {
docWidth = $(document).width();
docHeight = $(document).height();
});
//-->
</script>
Here's the snippet for TestPage.aspx.cs:
// using PageMethod for ajax
[System.Web.Services.WebMethod(EnableSession = true)]
public static string TestAjax()
{
System.Threading.Thread.Sleep(5000); // 5 seconds
// or do something else here
// ie. if validation error, throw an exception
return string.Empty;
}
UPDATE 1: added some javascript function
Why don't you call the .hide() on the post success:
$.ajax({
type : "Post",
url : "TestPage.aspx/TestAjax",
cache : false,
data : "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
// hide element when POST return as arrived,
// meaning the "5 seconds" period has ended!
o_animationDiv.hide();
}
});
You can read about callback function at the jQuery documentation!
jQuery ajax is asynchronous, so that won't wait for ajax result to hide again.
o_animationDiv.hide();
o_animationDiv.show();
This lines work in serial and you can't see if it's working properly. So you should wait for ajax result to hide it.Try this,
$.ajax({
type: "Post",
url: "TestPage.aspx/TestAjax",
async: false,
cache: false,
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json"
}).done(function() {
o_animationDiv.hide();
});
UPDATE:
Sorry I missed the point that you create a synchronous ajax request.
But there is a problem already. Most browsers lock itself when running a synchronous XHR. This also effects previous proccess sometimes.
Here is a similar question
Maybe if you use beforeSend, you can avoid this problem.
beforeSend
A pre-request callback function that can be used to modify the jqXHR
(in jQuery 1.4.x, XMLHTTPRequest) object before it is sent
Try this one,
$.ajax({
type: "Post",
url: "TestPage.aspx/TestAjax",
async: false,
cache: false,
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
beforeSend : function() {
o_animationDiv.show();
}
}).done(function() {
o_animationDiv.hide();
});
UPDATE-2:
If that doesn't work, try this one,
...
o_animationDiv.width(docWidth);
o_animationDiv.height(docHeight);
o_animationDiv.show();
setTimeout(function() {
$.ajax({
type: "Post",
url: "TestPage.aspx/TestAjax",
async: false,
cache: false,
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: testAjaxSuccess,
error: testAjaxError
}).done(function() {
o_animationDiv.hide();
});
}, 600);