Reputation: 59
I have a common generic function which will make use for ajax calls. While triggering the first time I will get the whole data from the server and I will maintain local scope. So In in the second time, it won't the server for the data. In my case the problem is the first request is async request while processing the first request second request is coming and again it is hitting the server. Now, how I can put the second request in waiting for state until the first request was finished?
a.js
will call the call.js
which has the ajax call: get();
b.js
also will call the same function. In the second the data was available in global
variable so that it won't make any ajax call: get();
call.js:
var get = function() {
var global = [];
if (Object.keys(global).length)
retrun global;
ajaxcall({
// ...
}).done(function(data) {
global = data;
}).fail(function(err) {
});
}
In this case while processing the first request second request is coming. So it is making another call.
Upvotes: 0
Views: 700
Reputation: 18526
To have just one request running to the server, and the next request has to wait until the first one is done
The question needs a couple more lines of code and has been answered before, so I will just link to a couple of examples. What you should be looking for are the keywords "ajax queue".
I would recommend using one of the available libraries for this case, but the first answer also gives an example of some library-free code.
To have just one request and cache the result
Usually the first thing to do would be to just keep track of your existing call.
var isCallInProgress = false;
var global = [];
var get = function() {
if (Object.keys(global).length)
return global;
if (isCallInProgress)
return;
isCallInProgress = true;
ajaxcall({
// ...
}).done(function(data) {
global = data;
isCallInProgress = false;
}).fail(function(err) {
});
}
Depending on your usecase, you may need to do some further work here. Returning the data immediately if its already loaded and returning nothing if its not is not really ideal. Something like this would be more along the usual expected API design:
var isCallInProgress = false;
var global = [];
var get = function(returnCallback) {
if (Object.keys(global).length){
// callback immediately
// you might also want to wrap this in a promise or setTimeout, depending on your expected behavior
returnCallback(global);
}
if (isCallInProgress)
return;
isCallInProgress = true;
ajaxcall({
// ...
}).done(function(data) {
global = data;
isCallInProgress = false;
// async callback
returnCallback(global);
}).fail(function(err) {
// error callback would probably also be appreciated by the caller
});
}
Upvotes: 2
Reputation: 708
The $.ajax
function, in jQuery, returns a jQuery XMLHttpRequest object, or jqXHR. That object can be stored, and functions can be run on it.
The best option would be to store the returned jqXHR or XMLHttpRequest in a globally accessible variable. In each of the two functions, check to see if that globally accessible variable is null. If it is, then run it. Once the ajaxcall has completed, clear the varname:
varname = ajaxcall({
// ...
})
// ...
.always(function(){
varname = null;
);
Upvotes: 0
Reputation: 386
You can use Promises API to solve this problem in an elegant manner.
//call.js
var DataPromise = new Promise(function(resolve, reject) {
ajaxcall({
// ...
}).done(resolve).fail(reject);
});
//a.js
DataPromise.then(function(data) { console.log("a.js now has the data"); });
//b.js
DataPromise.then(function(data) { console.log("b.js now has the data"); });
The Promises API will take care of tracking what is the status of DataPromise
and ensure ajaxcall is issued only once.
Upvotes: 0
Reputation: 1508
Perform your second request in the callback of your first request.
var get = function() {
var global = [];
if (Object.keys(global).length)
retrun global;
ajaxcall({
// ...
}).done(function(data1) {
global = data1;
//perform second request here, return data2
}).fail(function(err) {
});
}
Your second request won't execute until the first one has succeeded and invoked its callback.
Upvotes: 0
Reputation: 106
You can use the async: false
in ajax call, but this feature is deprecated. The best idea is create one control var.
var requestSucceded = false;
var get = function() {
var global = [];
if (Object.keys(global).length && requestSucceded)
return global;
ajaxcall({
// ...
}).done(function(data) {
global = data;
requestSucceded = true;
}).fail(function(err) {
});
}
Upvotes: 1