0

I assume because it is asynchronous. Here is my code:

service.getDistanceMatrix(
        {
            origins: [yourPosition],
            destinations: [end],
            travelMode: 'WALKING',
        }, callback);

        function callback(response, status) {
            if (status == 'OK') {
                var origins = response.originAddresses;
                for (var i = 0; i < origins.length; i++) {
                  var results = response.rows[i].elements;
                  for (var j = 0; j < results.length; j++) {
                    var element = results[j];
                    var distance = element.distance.value;
                    var duration = element.duration.value;
                  }
                }
            }

What I want to do is return the distance and duration values from the callback. Then, return that value, and feed it to the function that calls the parent function of my above code. What my brute force idea was was to return from within the callback, then return that received value from outside the callback function, so I can actually use the value. For sake of clarity, here is a diagram, as I understand, of my functions:

get_avg_speed
    get_distance
       callback

I know callbacks are async, is there a correct way to do this?

  • Related: https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Taplar Jun 04 '20 at 22:47
  • I agree, I believe I have the async part figured out, this callback function seems to handle the whole "promise" thing. I am just unsure how to catch the value if I were to return from within that callback function. Just a bit confused on how to apply the correct solution you sent to my particular problem I guess. –  Jun 04 '20 at 23:07

1 Answers1

0

Promise is your friend here. Here's your code using the Promise constructor. Binary callbacks like these are troublesome, so I put response and status in an object.

const promisifiedGetDistanceMatrix = params => new Promise(resolve => {
  service.getDistanceMatrix(params, (response, status) => {
    resolve({ response, status })
  })
})

const getElementsDistanceDuration = ({ response, status }) => {
  if (status !== 'OK') return []
  let elements = []
  let origins = response.originAddresses;
  for (let i = 0; i < origins.length; i++) {
    let results = response.rows[i].elements;
    for (let j = 0; j < results.length; j++) {
      let element = results[j];
      let distance = element.distance.value;
      let duration = element.duration.value;
      elements.push({ distance, duration })
    }
  }
  return elements
}

Then you can use these promise returning functions like this

const get_avg_speed = async (...args) => {
/* ... */
  const elementsDistanceDuration = await promisifiedGetDistanceMatrix({
    origins: [yourPosition],
    destinations: [end],
    travelMode: 'WALKING',
  }).then(getElementsDistanceDuration)
}
richytong
  • 2,387
  • 1
  • 10
  • 21