This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
Like a person asked here (but his solutions as to call a nother function) https://stackoverflow.com/a/10796326/315200 ...I would like to know if its possible to have a function which doesn't call a second function on response of an async request, but simply return when the async request responses.
Something like this maybe:
function callToFacebook() {
var fbResponse;
FB.api('/me', function (response) {
fbResponse = response;
});
return fbResponse; //Will return undefined because CallToFacebook is async
}
Isn't that possible some way, without calling another function??
What I'm trying to achieve is to have one function I can call with some parameters, which will return the response object from a async webservice, like FB.
In short, no. You cannot have an asynchronous function return a meaningful value synchronously, because that value does not exist at that time (as it is built asynchronously in the background).
You can, however, return a Promise object, representing the "potential return value" of the asynchronous operation, and bind a function to that object using done() or similar. That way, your function gets return semantics (instead of having to chain the control flow into a callback), and remains asynchronous.
No, it's not possible.
You can't return value that is returned from async operation.
Think about it, you tell 10 people to have one mile running contest, they start now, will finish in one minute +-, but you want to know the answer now, it's not possible unless you're cheating...
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I have a function which is returning information from an API call,part of which is an access token. I then need to plug that access token into the parameters of a redirect URL. Only problem is that thw redirect is invoked before the data is returned. Any ideas on how I can wait till the data is returned before invoking the redirect?
Here's the code:
oauthClient.createToken(req.url)
.then((authResponse) => {
oauth2_token_json = JSON.stringify(authResponse.getJson(), null,2);
let newToken = JSON.parse(oauth2_token_json)
accessToken = newToken.access_token
})
.catch((e) => {
console.error(e);
});
res.redirect(`http://localhost:3000/?token=${accessToken}`)
});
Add one more .then() and make sure the previous .then() returns the authToken (or any variable). Now run that logic of res.redirect(..).. in the next nested .then().
This way you are making sure, the code waits for the asynchronous part to finish off first. then-ables are the best way to make sure your code only runs once the promise is resolved. JavaScript executioner jumps to next line of code once it sees a asynchronous code block, i.e., could be a promise, .then()s, async-awaits.
This was the reason why, res.redirect() was running a little earlier.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I am relative new to node.js and I ran into a problem where a function is returning undefined. I use console.log to make sure that it returns the proper value and it does. But in the script that makes the call to the function shows as undefined. I think this may be an issue with async programming? I am trying to learn more on how promises work in node.js. What am I doing wrong?
The reason why I believe that it is a problem with async is because console.log is printing to the console undefined before the console.log in getCurrentFrameName();. var name is being assigned undefined.
frameHandler.switchToFrame('top_page');
var name = frameHandler.getCurrentFrameName();
console.log(name);
The console.log in this method prints to the console after the console.log in the code above. The value printed to the console of name is top_page.
this.getCurrentFrameName = function()
{
driver.executeScript('return self.name').then(function(name) {
console.log(name);
return name;
});
};
You can do this:
this.getCurrentFrameName = function(callback) {
driver.executeScript('return self.name').then(function(name) {
return callback(name);
});
};
and then call it like this:
frameHandler.getCurrentFrameName(function(name) {
console.log(name);
});
this will fix your problem, but yes, is a sync problem.
Yes, this is an issue with asynchronous programming. You cannot return a value from an asynchronous callback.
This is because the callback waits for the asynchronous script to execute, and so, node immediately passes control to the next line after the callback.
In your case, console.log(name); gets called before the callback is executed. Hence, the undefined.
The simplest solution to the current situation is to perform the necessary computations within the callback itself.
However, in more complicated situations (such as, callback within callback) you can easily end up with what is known as callback hell.
There are several ways to deal with callback hell: one of them is something called Promise.
What a Promise does essentially, is that it brings a sense of linearity to the code, thus making it easier to understand and maintain.
In your case, you can do this:
this.getCurrentFrameName = function() {
var myPromise = driver.executeScript('return self.name');
myPromise.then(function(name) {
// Do all computation with `name` here
});
};
This question already has answers here:
jQuery deferreds and promises - .then() vs .done()
(11 answers)
Closed 7 years ago.
There is not much answer for this simple question that I have. My main question is that I have seen the .then method used a lot in JavaScript and I know the main thing where randomobject.then(//This returns success, //this returns failure). But there are things that I don't get such as the code here:
var success = function (response) {
return response.data;
};
var error = function (errResponse) {
$log.error(errResponse.data.Message);
};
function getsomeData() {
var url = baseUrl + 'api/somedata';
return $http.get(url).then(success, error);
}
First off in that code I'm wondering how the var success knows what data it is getting and the same with error. It says response.data but what is response? It's probably the result of the http.get but that doesn't make much sense code wise. Also it seems that when I have a function for example.
getsomeData returns what it returns. Why doesn't it work if I do the ff:
var dataHolder = randomAngularService.getsomeData()
it returns an object that holds a data under $$state but somehow the .then makes it work if you do the ff:
randomAngularService.getsomeData().then(function (response) {
if(response != null) {
console.log('got the data');
$scope.meeData = response;
}
});
I thought the .then only takes two parameters? This is what's confusing me.
Also is the .then property a JavaScript method or a jQuery one?
It's used to replace (or provide an alternate way) the old callback mechanism with a cleaner way to handle asynchronous requests, instead of passing your callbacks as parameters, you can chain your function with .then, given function will be executed once the promise gets resolved.
Anyhow, this is just a basic explanation, you should really get into the books of promises for more info.
I'm lazy to explain the whole promise thing, but just to answer question about .then
The 2 arguments inside .then actually means "call this function when the promise is resolved(success)/rejected(failed)"
About the arguments inside the functions, they should be specified in the API, because the caller (for instance $http.get) get to decide what to pass when calling that function.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
The title might be a bit strange, but I'll try to explain.
I do an API call to validate some data. For this I use the following function:
function validateAddress(address) {
var validationURL = "/api/validateAddress/"+address;
$.getJSON(validationURL, function(data, textStatus, jqXHR){
if (textStatus === "success") {
return data.isValid
}
}));
}
// And then in other parts of the code I want to do something like:
if (validateAddress(address)) {
// do something awesome right here..
}
The problem with this is of course that it is an async call, which causes validateAddress() to not return anything, because it ends before the API call has returned any result.
So how can I actually make validateAddress() return the result of the api call? All tips are welcome!
You have few options:
you can either pass parameter to jQuery ajax functions to make the call synchroneous (you can't use getJSON though, you need to use $.ajax directly and pass it async: false)
you can pass callback into the validateAddress function as second parameter that you'll call when the request finishes
you can return the return value of $.getJSON call from the function validateAddress, since it's a promise, you can attach your code to that with the use of .done() (example of this is here http://api.jquery.com/jQuery.getJSON/#jqxhr-object)
How about something like:
function validateAddress(address) {
var validationURL = "/api/validateAddress/"+address;
return $.getJSON(validationURL);
}
and then use it like:
validateAddress("myaddress").done(function(response) {
// do my stuff here
});
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
I'm calling a C# api through Jquery AJAX. I am able to loop through all of the data and print each in the console; however, I am not able return the data to a variable (var x) so that it contains all objects returned from the api call.
This is my code thus far:
var uri = 'api/products';
function test(){
// Send an AJAX request
$.getJSON(uri)
.done(function (data) {
// On success, 'data' contains a list of products.
var info = {};
$.each(data, function (key, item) {
// Add a list item for the product.
console.log(item);
info.append(item);
});
return info;
});
}
var x = test();
I have tried to just simply skipping the $.each() and returning data, with no luck.
Should I be using a method other than append? Or is there a way to just simply return data?
Thanks.
.done() is a promise (http://api.jquery.com/promise/), which takes a callback function. The callback function is void; nothing consumes its return...and the return in your code is the return for the (anonymous) callback function, not for test(), which is why you're seeing no value come out.
This is an asynchronous pattern. That means test() is going to return immediately, not waiting for the AJAX call to complete, and there's no value yet to put into x! The AJAX response will arrive later, at some unknown time. The purpose of the callback function is to allow you to (at that time!) do whatever it is you intend to do with the value you receive. You haven't shown us what that is in this example, but you're going to need to restructure it to happen after the promise is fulfilled.