Nicholas Siegmundt
Nicholas Siegmundt

Reputation: 869

Node.js promise chain not running synchronously

Maybe I'm misunderstanding promises (again) but my promise chain isn't waiting for the previous promise to resolve before moving onto the next.

Here is my code:

function getLocations(){
  return new Promise((resolve, reject) => {
    request('https://api.sportradar.us/ncaamb/trial/v4/en/polls/ap/2017/rankings.json?api_key=MY_KEY', function (error, response, body) {
      resolve(body);
    });
  })
}

function convertLocations(body){
  return new Promise((resolve, reject) => {
    for(var i=0; i<15; i++){
      myLocation = JSON.parse(body).rankings[i].market

      var geocodeParams = {
        "address": myLocation
      }

      gmAPI.geocode(geocodeParams, function(err, result){
        areaLat = result.results[0].geometry.location.lat.toFixed(2);
        areaLong = result.results[0].geometry.location.lng.toFixed(2);
        console.log(areaLat + "  " + areaLong);
        locationString += areaLat + "  " + areaLong + "|";
      });

      params["markers"].push({location: myLocation})
    }

    resolve(locationString);
  })
}


getLocations()
.then((body) => convertLocations(body))
.then((locationString) => {
  console.log("HERE ---> " + locationString);
})

So the last thing that i want to be output in the console.log("HERE ---> " + locationString); but it gets output before anything else instead.. why is the last function in the promise chain not waiting for the other promises to resolve?

Upvotes: 0

Views: 126

Answers (1)

RidgeA
RidgeA

Reputation: 1546

Try this:

function getLocations() {
  return new Promise((resolve, reject) => {
    request('https://api.sportradar.us/ncaamb/trial/v4/en/polls/ap/2017/rankings.json?api_key=MY_KEY', function (error, response, body) {
      resolve(body);
    });
  })
}

function convertLocation(location) {
  return new Promise((resolve, reject) => {
    // do whatever you need to convert, i'm not sure if i was careful enough when I copy-paste you code

    var geocodeParams = {
      "address": myLocation
    }
    gmAPI.geocode(geocodeParams, function (err, result) {
      areaLat = result.results[0].geometry.location.lat.toFixed(2);
      areaLong = result.results[0].geometry.location.lng.toFixed(2);
      console.log(areaLat + "  " + areaLong);
      resolve(areaLat + "  " + areaLong + "|"); // <---- reosolve promise !!!
    });

  })
}

function convertLocations(body) {

  var promises = [];
  var data = JSON.parse(body);


  for (var i = 0; i < 15; i++) {
    promises.push(convertLocation(data.rankings[i].market));
  }

  return Promise.all(promises).then(arrayOfResulst => {
    return arrayOfResulst.join('')
  })
}


getLocations()
  .then((body) => convertLocations(body))
  .then((locationString) => {
    console.log("HERE ---> " + locationString);
  })

I'm not pretty sure I copied all correctly, and code could be written better (e.g. use reduce instead of for-loop), but i hope it will show you main idea.

Upvotes: 2

Related Questions