This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
How do I make a function to continue only after another function which was called by it finished. Something like this :
function FunctionOne() {
//Do something ...
FunctionTwo()
//Rest of the code after two is finished
}
function FunctionTwo() {
//Some code
}
EDIT:
The exact functions are like this :
function FunctionOne() {
//Do something ...
var result;
for (var i = 0 , i < 100 , ++i){
result = FunctionTwo()
}
//Rest of the code after two is finished
console.dir(result); //this here gives me undefined
}
function FunctionTwo() {
$.get("url", function(data)
{
result = data;
console.dir(result); //this gives me the data but the first function is still running and it finishes faster then the data is retured
return result;
}
You have to use jQuery.ajax and set async: false
a simple example:
result = '';
function FunctionTwo() {
jQuery.ajax({
url: 'url',
success: function(data) {
result = data;
console.dir(result);
},
async: false
});
alert(result);
}
This should already do as you request. Unless you specify FunctioTwo to run asynchronously it will block for you.
Edit in response to your edit:
If you want the Ajax call to block then there is no reason to have it as an async call, if you do wish it to remain async then utilize the callback of the ajax call to execute you data handling function instead of placing that code inside the main block.
function FunctionOne() {
//Do something ...
var result;
for (var i = 0 , i < 100 , ++i){
result = AJAXCall(i)
}
}
function HandleAJAXResponse(response,id)
{
console.dir(response)
}
function AJAXCall(id) {
$.get("url",function(data,id){
HandleAJAXResponse(data,id);
});
}
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
This is my custom jQuery function:
(function($){
$.fn.NotYet = function(arti_id) {
this.append(function() {
var result = 0;
$.post("comment_load.php", {arti_id:arti_id, status:1}, function(data){
console.log(data); // Returns data from POSTed PHP file
console.log(result); // Returns 0
//$(this).append(result); // Not Working
result = data;
console.log(result); // Returns data from POSTed PHP file
});
console.log(result); // Returns 0
return result; // Returns 0
});
return this; // Returns 0
};
})(jQuery);
I am calling the function like this:
$("div#Comments").NotYet(15);
I am trying to make a jQuery function, but I am unable to return the posted php file data back to into the <div> container.
Any suggestions?
FYI: This question is similar, but I could not understand what is happening and I needed a simple method. How do I return the response from an asynchronous call?
$.post is async method its cant return anything. And your problem is result value set before ajax call end.That why the console.log value as 0.
so you need to set inside the callback of success function.
And inside the call back this element as invalid one.So you need declare some another variable before pass to the success function like var that = this
Code:
(function($) {
$.fn.NotYet = function(arti_id) {
this.append(function() {
var that = this;
var result = 0;
$.post("comment_load.php", {
arti_id: arti_id,
status: 1
}, function(data) {
console.log(data); // Returns data from POSTed PHP file
$(that).append(data); //its work
result = data;
});
console.log(result); // Returns 0 //its excute before ajax call
return result; // its not possible
});
};
})(jQuery);
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
There is this small function that should logically returns always, but I am getting undefined :-
function hasAccess() {
var dataObj = {
"id" : $scope.groupId
};
$http.post('http://vlinux:9099/GetItems', dataObj).then(
function(response) {
var result = response.data.result;
if(result.includes($scope.screenId)) {
return "ok";
} else {
return "nok";
}
});
}
I started getting downvotes, so wuickly adding, I debugged it and saw http call is bringing expected response and flow is jumping to the right if/else block. Problem is when I am calling this function in a variable its storing undefined.
The call is simple too :-
var allow = hasAccess();
$http.post is not synchronous, but asynchronous.
Thus, all that you have after $http.post is a promise, not the boolean you are expecting.
The documentation show wells how to provide a "callback" to your function, in case of success as well as failure :
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
// for example : manageWHenOk
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
// for example : manageWHenKO
});
Your function return a result only if the request is fine. If there is an error your function do nothing! I suggest you to add a catch function.
function hasAccess() {
var dataObj = {
"id" : $scope.groupId
};
$http.post('http://vlinux:9099/GetItems', dataObj).then(
function(response) {
var result = response.data.result;
if(result.includes($scope.screenId)) {
return "ok";
} else {
return "nok";
}
}).catch(function (error) {
// do something
});
}
If you still have undefined it means that your template is loaded before to obtain the response. In order to resolve that you can do the request in the resolve method of the $stateProvider.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I have a function and a variable....
var imageURLs = retrieveRemoteImages(vinUrls)
if imageURLs !== undefined) {
// do something
}
function retrieveRemoteImages(urls) {
var imageURls = [];
processSpinnerActivity(START_IMAGES_IMPORT);
importImagesforSlideShow(REMOTE_IMAGES_URL, urls, function (images) {
if (images !== undefined) {
imageURls = images;
return imageURls;
}
})
return imageURls;
}
This does as intended ....
function importImagesforSlideShow(imagePath, urls, call_back) {
var functionName = 'importImagesforSlideShow'
$.ajax({
type: "POST",
url: LOCAL_PROCESSING_MODULE,
data: {data: [imagePath, urls, IMAGE_EXTENSION_QUALIFIER], functionid: functionName},
dataType:"json",
success: function (res) {
processSpinnerActivity(IMPORT_IMAGES_SUCCESS);
call_back(res);
},
error: function (err) {
processSpinnerActivity(IMPORT_IMAGES_ERROR);
console.log(err.message);
}
});
}
The callback works fine, but I am not able to pass the eventual value to imageURLs and I need to, as the next step cannot occur until it has a value.
Any ideas?
Thanks!
This is not a duplicate question, I have no issues with my AJAX returning the async value*
It's not possible like that, you are executing a piece of async code. So your code keeps running while their isn't any data yet. You have to process your data in a callback, for example like this:
function retrieveRemoteImages(urls, callback) {
processSpinnerActivity(START_IMAGES_IMPORT);
importImagesforSlideShow(REMOTE_IMAGES_URL, urls, callback);
}
retrieveRemoteImages(vinUrls, function(imageURLS) {
//do your stuff
});
I'm trying to do a little web in JavaScript + Ajax and I want to do it recursively. I've never used ajax before and the problem is I don't know to finish functions. The code looks like that:
var cont = 0;
var function1 = function (query) {
$.ajax({
url: '...',
data: {
.
.
.
},
success: function (response) {
instructions;
function2(param1, param2);
}
});
};
var function2 = function (query, param2) {
$.ajax({
url: '...',
data: {
.
.
.
},
success: function (response) {
instructions;
function3(param1, param2, param3);
}
});
};
var function3 = function (query, param2, param3) {
if (cont == 2) {
console.log("finish");
return;
}
var test = $.ajax({
url: '...',
data: {
.
.
.
},
success: function (response) {
if (...) {
cont++;
instructions;
var audio = new Audio(...);
audio.play();
audio.onended = function () {
instructions;
function3(query, param2, param3);
return;
};
} else {
instructions;
function3(query, param2, param3);
};
return;
}
});
return;
};
document.getElementById('search-form').addEventListener('submit', function (e) {
e.preventDefault();
function1(document.getElementById('query').value);
}, false);
So basically, when cont == 2I try to get out of javascript function3 with return; but some part of the program ( I don't know if the success: function (response) or the full javascript function3 ) is still running and instructions are being executed.
How could I solve this?
First off, the way to do this properly is to make use of jQuery's deferred objects.
As you have probably noticed, the program doesn't simply wait at the ajax request, and then proceed to the 'success' handler. This is because Javascript uses a non-blocking/waiting model. So you call $.ajax({params,...}), this sends the request, but whatever's after this will then immediately run, without waiting. Then, once the top level function has finished executing and nothing else is running, the response can be processed, and the 'success' handler is invoked.
So how to do this stuff properly? Start by arranging your request functions like this:
function doRequest1() {
return $.ajax({
url: '...',
data: {
.
.
.
}
});
}
function doRequest2(parameter) {
return $.ajax({
url: '...',
data: {
.
p: parameter
.
}
});
}
Notice that we aren't providing a success handler, but we are returning the value that $.ajax returns. This is a deferred object which is used to represent a request which has been sent, but for which a response hasn't been received/handled. You can attach a handler to the object like this:
var r1 = doRequest1();
r1.then(function() {
// Do stuff on success...
});
A nice thing about these objects is that they can be chained using 'then'.
'then' accepts a function which takes the value of the old request and produces a new request to do next:
var allRequests = doRequest1().then(function(result1) {
return doRequest2("hello");
});
The 'allRequests' variable is now a deferred object representing the result of doRequest2. How do you get this result? You use 'then()', just like any other deferred:
allRequests.then(function(result) {
alert("All requests completed. Result of last one: " + result);
});
Make sure that you understand how the result from 1 request can be used to set the parameters for the next one, or even decide which request to make next.
If you don't need one request's result to determine the next, rather, you just want to run a number of requests and wait for them all to complete, you can use a shortcut, 'when':
$.when(doRequest1(),doRequest2(), doRequest3()).then(function(result1,result2,result3) {
// All done
});
Another nice thing about deferreds is that they can be cancelled:
allRequests.abort();
Using the above, hopefully you can see how to restructure your code so you get a sequence of requests with a function to run after all 3 have completed.
Watch the value of your global variable cont through the flow of your program. It may be that it is (never) equal to 2 when function3() is called and that is why your program continues.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
The function I called inside jquery returns undefined. I checked the function and it returns correct data when I firebugged it.
function addToPlaylist(component_type,add_to_pl_value,pl_list_no)
{
add_to_pl_value_split = add_to_pl_value.split(":");
$.ajax({
type: "POST",
url: "ds/index.php/playlist/check_folder",
data: "component_type="+component_type+"&value="+add_to_pl_value_split[1],
success: function(msg)
{
if(msg == 'not_folder')
{
if(component_type == 'video')
{
rendered_item = render_list_item_video(add_to_pl_value_split[0],add_to_pl_value_split[1],pl_list_no)
}
else if(component_type == 'image')
{
rendered_item = render_list_item_image(add_to_pl_value_split[0],add_to_pl_value_split[1],pl_list_no)
}
}
else
{
//List files from folder
folder_name = add_to_pl_value_split[1].replace(' ','-');
var x = msg; // json
eval('var file='+x);
var rendered_item;
for ( var i in file )
{
//console.log(file[i]);
if(component_type == 'video')
{
rendered_item = render_list_item_video(folder_name+'-'+i,file[i],pl_list_no) + rendered_item;
}
if(component_type == 'image')
{
rendered_item = render_list_item_image(folder_name+'-'+i,file[i],pl_list_no) + rendered_item;
}
}
}
$("#files").html(filebrowser_list); //Reload Playlist
console.log(rendered_item);
return rendered_item;
},
error: function()
{
alert("An error occured while updating. Try again in a while");
}
})
}
$('document').ready(function()
{
addToPlaylist($('#component_type').val(),ui_item,0); //This one returns undefined
});
The function addToPlaylist doesn't return anything. It makes an asynchronous request, which eventually executes a callback function, which returns something. The original addToPlaylist function is long done and returned by the time this happens though, and the callback function returns to nobody.
I.e. the success: function(msg) { } code executes in a different context and at a later time than the surrounding addToPlaylist function.
Try this to see it in action:
function addToPlaylist() {
$.ajax({
...
success : function () {
alert('second'); // comes after 'first'
return null; // returns to nobody in particular
}
});
alert('first'); // comes before 'second'
return 'something'; // can only return here to caller
}
You're making your request via AJAX, which by definition is asynchronous. That means you're returning from the function before the AJAX request completes. In fact, your return statement is meaningless as it returns from the callback function, not your addToPlaylist function.
You have a couple of choices. The first one is better.
First, you can work with the asynchronous nature of the AJAX request and pass a callback into your addToPlaylist method (much like you're passing in the anonymous callback to the ajax function) and have the AJAX callback, call that function instead of doing the return. That way your request completes asynchronously and doesn't lock up your browser while it's going on.
function addToPlaylist(component_type, add_to_pl_value, pl_list_no, cb )
{
...yada yada yada...
$.ajax({
...
success: function(data) {
...
if (cb) {
cb.apply(this, rendered_item );
}
}
});
}
Second, you can add the option aSync: false to the ajax call. This will force the AJAX call to run synchronously (essentially it just loops until the call returns then calls your callback). If you do that, you need to capture a local variable in your addToPlaylist function inside the callback and assign the value(s) to it from the callback. At the end of the addToPlaylist function, return this variable as the result.
function addToPlaylist(component_type, add_to_pl_value, pl_list_no )
{
...yada yada yada...
var result = null;
$.ajax({
aSync: false,
...
success: function(data) {
...
result = rendered_item;
}
});
return rendered_item;
}
I agree with deceze. What you need to do is perform the necessary action(s) for rendered_item in the success function rather than relying on getting something back from addToPlayList().