Promise and callback function in ajax, when does success take place ? - javascript

Right now I have a code like this:
$.ajax({
url: apiUrl + valueToCheck,
data: {
format: 'json'
},
error: function () {
},
dataType: 'json',
success: function (data) {
checkAgainstDBHelperWH(data, valueToCheck);
},
type: 'GET'
});
If I am not mistaken, checkAgainstDBHelperWH is known as a callback function. The function executes once the servers sends back response for this particular HTTP /ajax request.
I want to try writing something like the one below, but I don't know what are the effects or is it even logical:
var request = $.ajax({
url: apiUrl + valueToCheck,
data: {
format: 'json'
},
error: function () {
},
dataType: 'json',
success: function (data) {
checkAgainstDBHelperWH(data, valueToCheck);
},
type: 'GET'
})
arrayOfPromises.push(request);
$.when.apply(null, arrayOfPromises).done(function () {
//...some javascript here
});
I want to understand if the .done(function () is fired after the callback function checkAgainstDBHelperWH is completed? Or whatever I am trying to write above does not flow consistently with how ajax works?
Thanks!

I tested it, your code only work if the function(in this case, 'checkAgainstDBHelperWH') doesn't call ajax.
If you want to wait finishing the inner ajax process, use then() and return inner ajax.
var ajaxs =
$.get("xxx").then(function() {
return $.get("yyy").done(function() {
});
});
Here is the jsfiddle.
I'm not sure whether this way is general or not.

Related

Multiple Ajax function calls cause slow to load

function function1(val)
{
$.ajax({
type: 'post',
url: 'page1.php',
data: {
get_option:val
},
success: function (response) {
document.getElementById("id1").value=response;
function2(val);
function3(val);
function4(val);
function5(val);
}
});
}
function function2(val)
{
$.ajax({
type: 'post',
url: 'page2.php',
data: {
get_option:val
},
success: function (response) {
document.getElementById("id2").value=response;
function6(val);
}
});
}
function function3(val)
{
$.ajax({
type: 'post',
url: 'page3.php',
data: {
get_option:val
},
success: function (response) {
document.getElementById("id3").value=response;
}
});
}
This is my some functions function1 success part I call other functions like function2, function3, function4, function5. In my Second function function2 I call another one function function6 on its success part its more time to get its resultsHow to avoid this wait time...?
If each of your ajax requests are returning results somewhat sequentially it's probably session blocking in effect. If the execution of the scripts can be performed simultaneously without affecting the results, try adding the following early in the PHP code:
session_write_close(); //let the next requests start
This will allow the subsequent ajax requests to begin PHP processing and should improve your results significantly.

Ajax - All request are Done/Completed

I have a difficulty to know when all Ajax requests are completed because I need this information to call another function.
Difficulty are to know when my 4/5 function with requests are completed. I use native function of ajax and none is working for me.
I used Chrome, and async requests.
Someone Helps me
I use this(not work):
$(document).ajaxStop(function() {
alert("Completed");
});
and this (not Work):
$(document).ajaxComplete(function() { alert("Completed"); });
Both ways I try use in another function thal calls all requests:
Example:
function Init()
{ Search("123"); Search2("1234"); Search3("12345");
... }
Extract one (of 5 requests,others are very similar ) of my request:
function Search(user) {
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP',
success: function(response, textStatus, jqXHR) {
try {
if (response != null) {
alert("Have Data");
} else {
alert("are empty");
}
} catch (err) {
alert("error");
}
},
error: function() {
alert("error");
}
}); }
have you tried putting it in a done function? something like...
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP'
}).done(function (data) {
code to execute when request is finished;
}).fail(function () {
code to do in event of failure
});
bouncing off what Michael Seltenreich said, his solution, if i understand where you guys are going with this...might look something like:
var count = 0;
function checkCount(){
if(count == 5 ){
//do this, or fire some other function
}
}
#request one
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP',
}).done( function(data){
count += 1
checkCount()
})
#request two
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP',
}).done( function(data){
count += 1
checkCount()
})
and do it with your five requests. If that works out for you please make sure to mark his question as the answer;)
You can create a custom trigger
$(document).trigger('ajaxDone')
and call it when ever you finished your ajax requests.
Then you can listen for it
$(document).on('ajaxDone', function () {
//Do something
})
If you want to keep track of multiple ajax calls you can set a function that counts how many "done" values were passed to it, and once all are finished, you can fire the event.
Place the call for this function in each of the 'success' and 'error' events of the ajax calls.
Update:
You can create a function like so
var completedRequests= 0
function countAjax() {
completedRequests+=1
if(completedRequests==whatEverNumberOfRequestsYouNeed) {
$(document).trigger('ajaxDone');
}
}
Call this function on every success and error events.
Then, ajaxDone event will be triggered only after a certain number of requests.
If you wanna track specific ajax requests you can add a variable to countAjax that checks which ajax completed.

Can this JavaScript Defer code be simplified?

I have a JavaScript bootstrapper module that I'm trying to keep very clean and simnple: Currently I have code like:
function bootStrapper() {
xmlRepository.getAll().done(function (result) {
autoPolicyForm.show();
});
}
In xmlRepository I am using a deferred object within getAll();
function getAll () {
var d = $.Deferred();
$.ajax({
type: "GET",
url: "http://localhost/Autopolicy/dataSource.xml",
dataType: "xml",
success: function (xml) {
d.resolve(xml);
}
});
return d.promise();
}
This code is working well but I would really like to simplify the bootstrapper code further to something like:
function bootStrapper() {
var result = xmlRepository.getAll();
autoPolicyForm.show();
});
}
Everything I try results in 'result' being undefined due to the async nature of call.
Does anyone know how to modify the code to move the complexity to the xmlRepository so that the above can be achieved?
Thanks
In modern jQuery the ajax function returns a promise so you can simplify getAll to :
function getAll () {
return $.ajax({
type: "GET",
url: "http://localhost/Autopolicy/dataSource.xml",
dataType: "xml"
});
}
In other words it is now possible to do
$.ajax(url).done(function(xml){...});
You could also change getAll to
function fetchAll (callback) {
$.ajax({
type: "GET",
url: "http://localhost/Autopolicy/dataSource.xml",
dataType: "xml"
}).done(callback);
}
So you'll do
xmlRepository.fetchAll(function (result) {
autoPolicyForm.show();
});
But apart setting async to false, you can't avoid passing a function as the execution is asynchronous. And you should consider that a javascript application is naturally event based so it's fine for the users of an API to use and pass anonymous functions (callbacks).

Is there any way to wait for AJAX response and halt execution?

Here is some code I'd like to execute. I'd like to wait for AJAX response so I can return something from the server. Any way to achieve this?
function functABC(){
$.ajax({
url: 'myPage.php',
data: {id: id},
success: function(data) {
return data;
}
});
//Wait for AJAX (???)
}
var response = functABC();
When using promises they can be used in a promise chain.
async=false will be deprecated so using promises is your best option.
function functABC() {
return new Promise(function(resolve, reject) {
$.ajax({
url: 'myPage.php',
data: {id: id},
success: function(data) {
resolve(data) // Resolve promise and go to then()
},
error: function(err) {
reject(err) // Reject the promise and go to catch()
}
});
});
}
functABC().then(function(data) {
// Run this when your request was successful
console.log(data)
}).catch(function(err) {
// Run this when promise was rejected via reject()
console.log(err)
})
New, using jquery's promise implementation:
function functABC(){
// returns a promise that can be used later.
return $.ajax({
url: 'myPage.php',
data: {id: id}
});
}
functABC().then( response =>
console.log(response);
);
Nice read e.g. here.
This is not "synchronous" really, but I think it achieves what the OP intends.
Old, (jquery's async option has since been deprecated):
All Ajax calls can be done either asynchronously (with a callback function, this would be the function specified after the 'success' key) or synchronously - effectively blocking and waiting for the servers answer.
To get a synchronous execution you have to specify
async: false
like described here
Note, however, that in most cases asynchronous execution (via callback on success) is just fine.
The simple answer is to turn off async. But that's the wrong thing to do. The correct answer is to re-think how you write the rest of your code.
Instead of writing this:
function functABC(){
$.ajax({
url: 'myPage.php',
data: {id: id},
success: function(data) {
return data;
}
});
}
function foo () {
var response = functABC();
some_result = bar(response);
// and other stuff and
return some_result;
}
You should write it like this:
function functABC(callback){
$.ajax({
url: 'myPage.php',
data: {id: id},
success: callback
});
}
function foo (callback) {
functABC(function(data){
var response = data;
some_result = bar(response);
// and other stuff and
callback(some_result);
})
}
That is, instead of returning result, pass in code of what needs to be done as callbacks. As I've shown, callbacks can be nested to as many levels as you have function calls.
A quick explanation of why I say it's wrong to turn off async:
Turning off async will freeze the browser while waiting for the ajax call. The user cannot click on anything, cannot scroll and in the worst case, if the user is low on memory, sometimes when the user drags the window off the screen and drags it in again he will see empty spaces because the browser is frozen and cannot redraw. For single threaded browsers like IE7 it's even worse: all websites freeze! Users who experience this may think you site is buggy. If you really don't want to do it asynchronously then just do your processing in the back end and refresh the whole page. It would at least feel not buggy.
nowadays I prefer using async function and await syntax
async function functABC(){
await $.ajax({
url: 'myPage.php',
data: {id: id},
success: function(data) {
return data;
}
});
//Wait for AJAX
}
Try this code. it worked for me.
function getInvoiceID(url, invoiceId) {
return $.ajax({
type: 'POST',
url: url,
data: { invoiceId: invoiceId },
async: false,
});
}
function isInvoiceIdExists(url, invoiceId) {
$.when(getInvoiceID(url, invoiceId)).done(function (data) {
if (!data) {
}
});
}
async: true
When we request for some data to a server, then server will may take some time to return a response. Now During this time browser interpreter resume execution it will not wait for response and continues it's execution. So that response may print second and other code output will be print first. This happens due to async is set to true. Now question arise that what this parameter does. async means asynchronously. This attribute tells to interpreter that do not does execution sequentially.
async: false
Means forcing that complete execution of this call/code first and then go for next. So it is depends on your requirement that how you use this attribute.
Example with async:
function ayncfunction() {
$.ajax({
url: 'abc.php',
data: {id: id},
async: true,
success: function(repsonse) {
return repsonse;
}
});
}
Example without async
function ayncfunction(){
$.ajax({
url: 'abc.php',
data: {
id: id
},
async: false,
success: function(repsonse) {
return repsonse;
}
});
}
use async:false attribute along with url and data. this will help to execute ajax call immediately and u can fetch and use data from server.
function functABC(){
$.ajax({
url: 'myPage.php',
data: {id: id},
async:false
success: function(data) {
return data;
}
});
}
Method 1:
function functABC(){
$.ajax({
url: 'myPage.php',
data: {id: id},
success: function(data) {
return data;
},
complete: function(){
// do the job here
}
});
}
var response = functABC();
Method 2
function functABC(){
$.ajax({
url: 'myPage.php',
data: {id: id},
async: false,
success: function(data) {
return data;
}
});
// do the job here
}

ajax call doesnt return the data from external JS file

I am trying to implement Repository pattern in JavaScript. I have ViewModel which i want to initialize with the data when i call Initialize method on it. Everything seems to be falling in places except that i am not able to return the data from my AJAX call. I can see that data is coming back from the ajax call but when i trying to capture the data in SomeViewModel's done function, it is null.
Can someone please point me out where i am going wrong here?
P.S: Please notice that i am not making Async call so the call chain is properly maintained.
This is how my Repository looks like:
function SomeRepository(){
this.LoadSomeData = function loadData()
{
$.ajax({
type: "POST",
url: "someUrl",
cache: true,
async: false,
contentType: "application/json; charset=utf-8",
data: "{}",
dataType: "json",
//success: handleHtml,
success: function(data) {
alert('data received');
return data;
},
error: ajaxFailed
});
function ajaxFailed(xmlRequest) {
alert(xmlRequest.status + ' \n\r ' +
xmlRequest.statusText + '\n\r' +
xmlRequest.responseText);
}
}
};
This is how my ViewModel looks like:
function SomeViewModel(repository){
var self = this;
var def = $.Deferred();
this.initialize = function () {
var def = $.Deferred();
$.when(repository.LoadSomeData())
.done(function (data) {
def.resolve();
});
return def;
};
}
This is how i am calling from an aspx page:
var viewModel = new SomeViewModel(new SomeRepository());
viewModel.initialize().done(alert('viewmodel initialized'));
alert(viewModel.someProperty);
I have used successfully an auxiliar variable to put the ajax result, when ajax call is inside a function (only works if ajax is async=false) and i need the function does return the ajax result. I don't know if this is the best solution.
function ajaxFunction(){
var result='';
$.ajax({
type: "POST",
url: "someUrl",
cache: true,
async: false,
contentType: "application/json; charset=utf-8",
data: "{}",
dataType: "json",
//success: handleHtml,
success: function(data) {
alert('data received');
result=data;
},
error: ajaxFailed
});
return result;
}
Doesn't matter that it's synchronous (though it really shouldn't be). Returning a value from inside the ajax callback will not cause the value to be returned from the containing function.
Using asynchronous ajax is generally a much better idea anyway, but that will force you to create an API that allows its clients to pass in handlers to be called when the ajax request completes. To do that, you'd give your "LoadSomeData" function a parameter. A caller would pass in a function, and your ajax "success" handler would pass on the results (or some transformation of the results; depends on what it is that you're doing) to that callback. It's the same idea as the callbacks used in the ajax call itself.

Categories

Resources