ChatGPT解决这个技术问题 Extra ChatGPT

How to return value from an asynchronous callback function? [duplicate]

This question already has answers here: How do I return the response from an asynchronous call? (43 answers) Closed 7 years ago.

This question is asked many times in SO. But still I can't get stuff.

I want to get some value from callback. Look at the script below for clarification.

function foo(address){

      // google map stuff
      geocoder.geocode( { 'address': address}, function(results, status) {
          results[0].geometry.location; // I want to return this value
      })

    }
    foo(); //result should be results[0].geometry.location; value

If I try to return that value just getting "undefined". I followed some ideas from SO, but still fails.

Those are:

function foo(address){
    var returnvalue;    
    geocoder.geocode( { 'address': address}, function(results, status) {
        returnvalue = results[0].geometry.location; 
    })
    return returnvalue; 
}
foo(); //still undefined
Anyone who got here please read this question first. It explains how to tackle this problem effectively.
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference also provides a more general, detailed explanation of the issue at hand.
Use Q, or any of it's variants, like $q library that comes with angularJs. And Never look back. Asynchronous functions immediately returns undefined. So never Waste your time trying do stuff on undefined. Also never use 'return' keyword in your async functions, as you normally do . Use deferred promises instead. deferred.resolve(STUFF you want to do) , then later you can simply return that ,'return deferred.promise; '. :)
use deasync like this stackoverflow.com/a/47051880/2083877

S
Sean Kinsey

This is impossible as you cannot return from an asynchronous call inside a synchronous method.

In this case you need to pass a callback to foo that will receive the return value

function foo(address, fn){
  geocoder.geocode( { 'address': address}, function(results, status) {
     fn(results[0].geometry.location); 
  });
}

foo("address", function(location){
  alert(location); // this is where you get the return value
});

The thing is, if an inner function call is asynchronous, then all the functions 'wrapping' this call must also be asynchronous in order to 'return' a response.

If you have a lot of callbacks you might consider taking the plunge and use a promise library like Q.


:) It's not strong, it's just how it is. As soon as you use an async method to pass data the entire function chain becomes asynchronous.
Upvote for finally making this make sense.
"you cannot use an asynchronous call inside a synchronous method." - Yes you can. You just can't use the async call's result from within the same synchronous method.
@Sean Kinsey,Can you tell me how to access location variable outside foo() function?
Just so we're clear, this won't let you "return" the value of that variable in a way that PHP returns it. We're basically passing result of one callback function to another call back function. There's still no outside var that actually holds the result...
P
Pointy

It makes no sense to return values from a callback. Instead, do the "foo()" work you want to do inside your callback.

Asynchronous callbacks are invoked by the browser or by some framework like the Google geocoding library when events happen. There's no place for returned values to go. A callback function can return a value, in other words, but the code that calls the function won't pay attention to the return value.


Yes, it makes fun sense to try and return a value from a promise callback. Unfortunately, it is not possible. For example, you may be crafting a class to scrape complex data from a website, and some data need to be retrieved through a http request. Using a fetch, you will never be able to make this class return an complex object with all the data (only using the blessed and deprecated xmlhttprequest). Using fetch, your class would need to mix different concerns and write the results into a database or other persisting method from inside the callbacks, according to the promises answers flow.
A
Alex Heyd

If you happen to be using jQuery, you might want to give this a shot: http://api.jquery.com/category/deferred-object/

It allows you to defer the execution of your callback function until the ajax request (or any async operation) is completed. This can also be used to call a callback once several ajax requests have all completed.