How to asynchronize multiple Ajax Post call to the same URL - javascript

I've an array of items in javascript, and for each item, I've to make an ajax post to a URL to get corresponding info and display the info in a container. The code broadly looks like this:
var data = some_data;
array.forEach(item, idx)=> {
callAjaxAndUpdate(data, item, $('div#container'+i);
});
and the Ajax method is simply
var standardUrl = 'https://example.com/post.php';
function callAjaxAndUpdate(data, item, container) {
$.ajax({
url: standardUrl
data: data,
type: 'POST',
}).done(function(res) {
container.append(res.data);
}).fail(function(res) {
container.append(res.responseText);
}).always(function() {
container.append('DONE!');
});
}
However, this thing whole thing seems to have become blocking. I did server-side logging of timestamps, and I could see that ajax request for each item is getting triggered only after that for the previous one has completed (always section executed).
Could someone help me out with why this setup is synchronous, and how to make it async? Please note that this script is executing in the browser, and not on nodeJS.
EDIT: Turns out, it's the PHP backend which is processing the requests in a blocking way. Perhaps the session is the culprit here. I would close the question now. Thanks for your help and suggestions.

Try default Ajax async
var standardUrl = 'https://example.com/post.php';
function callAjaxAndUpdate(data, item, container) {
$.ajax({
url: standardUrl,
async: true,
data: data,
type: 'POST',
}).done(function(res) {
container.append(res.data);
}).fail(function(res) {
container.append(res.responseText);
}).always(function() {
container.append('DONE!');
});
}
Or you can call the method on .done method

Related

Keeping AJAX Requests Serial in jQuery

I have some code that I recently moved to FastCGI for a backend to fulfill AJAX requests from a jQuery based front end. The problem is that while FastCGI largely accelerates it, I actually get a negative performance issue from two jQuery AJAX requests hitting it in too quick of succession. What I'd like to do is "lock" AJAX so that the requests happen in serial rather than parallel -- each request only takes around 180ms to perform, but if the second request goes in before the first one has completed, the second request ends up taking about a second and a half instead.
I suppose the obvious way that I could make it serial is to put an $.ajax request inside the .done portion of the previous request, but the requests are in to different functions and need to stay that way since they don't always need to be fired together -- just frequently so. Imagine this:
function loadCategories () {
// Do some organizing stuff, set url, etc.
$.ajax({
url: url,
data: parameters,
type: "GET",
dataType : "json",
})
.done(function( json ) {
//process sidebar category data.
});
}
function loadArticles () {
// Do some organizing stuff, set url, etc.
$.ajax({
url: url,
data: parameters,
type: "GET",
dataType : "json",
})
.done(function( json ) {
//process article data.
});
}
Both of these functions are called in a third function:
function loadPage (parameters) {
loadCategories(parameters);
loadArticles(parameters);
}
What I'd like to do is keep the .done and .always logic within those two functions, but also return a promise from these functions so that I could then use $.then to keep loadArticles from firing until loadCategories has completed. I've tried to figure out the right way to do this, but haven't succeeded in the right way to do this yet.
Have the functions return the Deferred object that $.ajax() returns, and then you can wait for this in the calling function.
function loadCategories() {
// Do some organizing stuff, set url, etc.
return $.ajax({
url: url,
data: parameters,
type: "GET",
dataType: "json",
})
.done(function(json) {
//process sidebar category data.
});
}
function loadArticles() {
// Do some organizing stuff, set url, etc.
return $.ajax({
url: url,
data: parameters,
type: "GET",
dataType: "json",
})
.done(function(json) {
//process article data.
});
}
function loadPage(parameters) {
$.when(loadCategories(parameters)).then(
function() {
loadArticles(parameters)
};
});
}

How to run getJSON synchronously? [duplicate]

GOAL: What I'm after is to get data from database and refresh main.php (more evident through draw_polygon) every time something is added in database (after $.ajax to submit_to_db.php).
So basically I have a main.php that will ajax call another php to receive an array that will be saved to database, and a json call another php to return an array will be used by main.php.
$(document).ready(function() {
get_from_db();
$('#button_cancel').click(function(){
$.ajax({
url: 'submit_to_db.php',
type: 'POST',
data: {list_item: selected_from_list},
success: function(result){
...
get_from_db();
}
});
});
function get_from_db(){
$.getJSON('get_from_db.php', function(data) {
...
draw_polygon(data);
});
}
});
In my case, what I did was a get_from_db function call for getJSON to actually get data from database, with the data to be used to draw_polygon. But is that how it should be done? I'm a complete newbie and this is my first time to try getJSON and ajax too to be honest. So my question: How does asynchronous work actually? Is there another workaround for this instead of having to call function get_from_db with getJSON (it isn't synchronous, is it? is that why it doesn't update the page when it isn't within a function?) All the time - like $.ajax with async: false (I couldn't get it to work by the way). My approach is working, but I thought maybe there are other better ways to do it. I'd love to learn how.
To make it more clearer, here's what I want to achieve:
#start of page, get data from database (currently through getJSON)
Paint or draw in canvas using the data
When I click the done button it will update the database
I want to AUTOMATICALLY get the data again to repaint the changes in canvas.
Since $.getJSON() uses ajax configurations, just set the global ajax configs:
// Set the global configs to synchronous
$.ajaxSetup({
async: false
});
// Your $.getJSON() request is now synchronous...
// Set the global configs back to asynchronous
$.ajaxSetup({
async: true
});
Asynchronusly does mean the Request is running in the background, and calls your function back when it got a response. This method is best if you want to have a result but allow to use your app within the request. If you want to have a direct response, take a look at a synchron request. this request will pause script execution until it got a response, and the user can not do anything until the response was recieved. You can toggle it via:
async: false,
So for example:
$.ajax({
url: "myurl",
async: false,
...
})
$.getJSON(), doesn't accept a configuration, as it says in the docs it's a shorthand version of:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
So just rewrite your request in terms of that and async:false will work just as you expect.
$.getJSON() is a shorthand notation for $.ajax() which can be configured to be synchronous (see jQuery.getJSON and JQuery.ajax):
$.ajax({
dataType: "json",
url: url,
data: data,
async: false,
success: function(data) {
...
draw_polygon(data);
}
});
Try to avoid synchronous calls though. Quote from jQuery doc (see async prop):
Cross-domain requests and dataType: "jsonp" requests do not support
synchronous operation. Note that synchronous requests may temporarily
lock the browser, disabling any actions while the request is active.
You might want to try jQuery Deferreds like this:
var jqxhr = $.getJSON(url);
jqxhr.done(function(data) {
...
draw_polygon(data);
});

returning value from js method with ajax call to REST service

What I am trying to do is call a js method that uses ajax to call a REST service and then return that response to the original call. Sounds simple enough, but I haven’t been able to find a sufficient answer here on SO to get it to work.
If async is true, I get undefined. If I set async to false, it works, but it is holding up the loading of the page. I have tried several attempts with different examples of using promises and callbacks, but just haven’t been able to figure it out. I know that there is something very basic I am missing, or concept I am failing to grasp.
In this example, I am wanting to check if an item is on a persons watch list for an auction. If it is, then it will set the icon class to active so it will change the icon color and they can see that it is on their watch list. If it is not, it remains greyed out.
Each page will have a few things like this example.
Page1.php
jQuery(document).ready(function($){
var w = mgapp.checkWatchlist($id, localStorage.u_pcjid);
if(!w.error){
$("#watchlist").removeClass('watchlist').addClass('watchlist-active');
}
});
The method is on the script.js page. The data returned from the ajax call is a JSON object.
NOTE: async is currently set to false just to get it to work.
script.js
var mgapp = {
checkWatchlist: function($iid, $uid) {
var $msg;
$.ajax({
url: 'https://somedomain/api/v1/watchlist/item/' + $iid + '/' + $uid,
type: "GET",
headers: {"Authorization": localStorage.u_apikey},
contentType: 'application/json',
async: false
})
.done(function(data){
$msg = data;
})
.fail(function(data){
$msg = data;
});
return $msg;
}
}
I am sure I will need to have a callback function or something, but none of the attempts I have made with those have worked.
Just to clarify. All the code is working as is, it is just not working asynchronously. What I am wanting is to have async set to true so that i am making an actual asynchronous call so that this is not holding up the loading of the page. I need the value returned from the ajax call available to the var on Page1.php.
Thanks in advance.
If figured it out.
var w = mgapp.checkWatchlist($id, localStorage.u_pcjid).done(function() {
if(!w.responseJSON.error){
$("#watchlist").removeClass('watchlist').addClass('watchlist-active');
}
})
checkWatchlist: function($iid, $uid) {
return $.ajax({
url: 'https://somedomain.c9.io/api/v1/watchlist/item/' + $iid + '/' + $uid,
type: "GET",
headers: {"Authorization": localStorage.u_apikey},
contentType: 'application/json'
})
},

Wait for Async ajax to complete before moving onto other code?

I know this has been asked, probably, a million times, but for the life of me I cannot get anything to work.
I have a UI wizard control that on the "changed" event validates the model. If the model is not valid, it doe not allow the user to move forward in the wizard. I have tired using the $.when().done() feature in jquery, but my code still passes through before making sure the model is valid. The reason for calling an async ajax request is I do not want the UI to lock up so I can show some sort of progress indicator. I had set the async property to false, but my UI indicator would never show up. Here is an example of what my code is doing:
//the change event that is called when the user clicks 'next' on the wizard:
wizard.on('change', function (e, data) {
var isValid = $.validate({
"Model": [The_UI_MODEL],
"Url": [URL_To_Server_Validation],
"Async": true, //tells ajax request to send as async
});
//Tells the wizard not to move 'next' if the request comes back as not valid
if (data.direction === 'next' && !isValid) {
e.preventDefault();
}
}
//I am using the $.extend method for JQuery to create a function that will validate any model in my system.
validate: function(options) {
//Clear any previous validation errors
$.clearValidations();
var data = $.postJson(options);
//the result is getting returned before the $.postJson(options) finishes
return data.Success;
}
//I created my own method that extends the $.ajax method so I could do other things before /after a request:
postJson: function(options){
...other code for my application
//This is where I want the ajax request to happen and once done return the data coming back
//This is what I have tried, but it is not doing what I thought.
$.when(function(){
return $.ajax({
url: options.Url,
type: 'POST',
cache: false,
async: options.Async,
timeout: options.Timeout,
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: JSON.stringify(options.Model),
error: function(xhr, status, error) {
...do stuff if ajax errors out
},
success: function (data) {
},
});
}).done(function(response){
//looks like i get back the responseText of the request. which is fine, but other posts i have read stated i should be getting back the request itself
...other UI stuff
return response;
})
}
KarelG is absolutely right. You need to refactor your code and do your valdiation check within the success callback of the ajax request.
Something like this...
wizard.on('change', function (e, data) {
$.ajax({
url: [URL_To_Server_Validation],
type: 'POST',
cache: false,
async: true,
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: {"Model": [The_UI_MODEL]},
success: function (response) {
//Tells the wizard not to move 'next' if the request comes back as not valid
if(!response & data.direction === 'next')
{
e.preventDefault();
}
}
});
});
It looks like you're trying to write asynchronous code as if it were synchronous. An asynchronous call such as your $.validate() will return immediately without a result and continue on to the rest of your code. Anything you want to happen when the validate call finishes must be done in a callback function passed to it.
You can use jQuery promises (when, then, done, etc.) or another library such as async.js to help manage the control flow.
Also, this isn't particularly useful now since there's little to no browser support for it yet, but the yield operator plus a library such as Task.js will eventually let us write asynchronous code as if it were synchronous.

AJAX Getting Data, Post Back and Get Again

I'm trying to do the following thing with AJAX:
Visitor click button/ AJAX show spinning/loading image to visitor.
AJAX Visit URL 1 http://www.mywebsite.com/url1.php and it'll return a random code, for example 1357.
Then, I want it to visit URL 2 http://www.mywebsite.com/url2.php?code=1357&action=ask (1357 is a variable from url1). URL 2 will verify the request return a final code. I want to show the code to the visitor after removing the spinning/loading image.
How do I do that?
Thanks in advance.
Try this.
$.get("http://www.mywebsite.com/url1.php").done(function(data){
$.get(
"http://www.mywebsite.com/url2.php",
{code: data, action: "ask"}
).done(function(next){
$("#result").html(next);
});
});
Try this:
$.ajax({
url: 'http://www.mywebsite.com/url1.php',
dataType: 'html',
type: 'GET',
success: function (data) {
// Show the random code, like 1357
$(".result").html(data);
$.ajax({
url: 'page2.php?rand_n=' + data, // Change rand_n to what you want
dataType: 'html',
type: 'GET',
success: function (data2) {
// Hide the spinning/loading image
$("#loading_img").hide();
// Show final code
$(".result").html(data2);
}
});
}
});
Here is my idea for you:
Method one:
1.ajax request http://www.mywebsite.com/url1.php
2.in url1.php generate a random code like :1357
3.use [curl][1] request http://www.mywebsite.com/url2.php?code=1357&action=ask
4.echo result from curl2 to frontend
above only need one time ajax,the second request use curl quietly..
Method two:
you also could use header to redirect the url:
go on with step 2:
step 3:could use header('Location: http://www.mywebsite.com/url2.php?code=1357&action=ask');
step 4:url2.php should echo the result.
this tow method only have one ajax request and won't affect you frontend ,i recommand you use method two,method one is better used in different domain..

Categories