0

I've been reading everything I can about async/await and Promises, but I can't quite get it to work. I keep getting 'Promise ' and when it's fulfilled I receive 'Undefined'.

I think I've spent about two days on this! I'm not sure what's wrong. Here's the un-promisified version.

  const getCoords = (address) => {
    geocoder.addressSearch(address, (result) => {
        return result;
      }
    );
  };

And here is my attempt at the promised code:

  const getCoords = async (address) => {
     await geocoder.addressSearch(address, async (result) => {
        return result;
  }
);

};

I'm just trying to return the result. If anyone could steer me in the right direction it would be really appreciated.

Jack Joseph
  • 109
  • 2
  • 7

1 Answers1

3

Both of your examples are incorrect

using continuation-passing style

In this style, the continuation ("callback") ignores any return values as this function is run asynchronously from the main call -

const geocoder =
  { addressSearch: (address, callback) =>
      setTimeout(callback, 1000, {
        coords: [12.345, 67.890]
      })
  }
  
const getCoords = (address, callback) =>
  geocoder.addressSearch(address, result =>
    callback(result.coords)
  )
  
getCoords("foobar", console.log)
// [ 12.345, 67.89]
[ 12.345, 67.89]

using promises

In this style you do not specify a continuation. Instead a Promise is returned which represents the value of a future computation. You can await a promise in an async function in order to retrieve the result, or chain a .then handler -

const geocoder =
  { addressSearch: (address, callback) =>
      setTimeout(callback, 1000, {
        coords: [12.345, 67.890]
      })
  }
  
const getCoords = (address) =>
  new Promise(resolve =>
    geocoder.addressSearch(address, result =>
      resolve(result.coords)
    )
  )
  
async function main() {
  const coords = await getCoords("foobar")
  console.log(coords)
  return "done"
}
  
main().then(console.log, console.error)
[ 12.345, 67.89]
"done"
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • Wow, this is very thorough and excellently written. My only problem is that I previously define geocoder like this: const geocoder = new kakao.maps.services.Geocoder(); So I'm having an issue with the first line of your answer. Do you have a suggestion around it? – Jack Joseph May 11 '21 at 01:57
  • I used a "fake" implementation of `geocoder` in my examples so we can see how they work and they can be tested here on the site in your own browser. If `kakao.maps.services.Geocoder` is written in continuation-passing style, you will write `getCoords` like we did in the first example. If `Geocoder` offers a promise-based API, you will write `getCoords` like we did in the second example. – Mulan May 11 '21 at 13:03
  • Note, if it is written using callback style, it is likely to follow Node's [error-first callback convention](https://nodejs.org/en/knowledge/getting-started/control-flow/what-are-callbacks/). See [this Q&A](https://stackoverflow.com/a/33086864/633183) for additional explanation and [this Q&A](https://stackoverflow.com/a/66873117/633183) for examples how to use with `async` and `await`. If you are stuck after that, please documentation to the link the library you are using and I will try to look into it. – Mulan May 11 '21 at 13:04