Wayfarer Wayfarer - 10 months ago 57
Javascript Question

Waiting for multiple (async) API calls to complete

Very much a nodejs noob, trying to make sense of promises, await, async. I promise you I did my due diligence research (spent the entire day studying to get the code hereunder. I'm still not entirely sure everything is as it should be and can find no reference that has the exact same thing (or close enough) to what I'm trying to do here.

Thanks for any help.

General structure:

function msg() is waiting for 4 functions to complete, the 4 api calls (code only shows one): function redditPromise().

redditPromise() calls async function redditGet() -> that's the one that will call reddit API and in the meantime save the API data to database. (function saveToDb())

var nodeSocialApi = require('node-social-api');
var Socstat = require('../proxy').Socstat;

exports.index = function (req, res, next) {

/* SAVES DATA TO MONGODB */
function saveToDb(website,total) {
//** Start : NewAndSave
Socstat.newAndSave(website, total, "random", function (err, socstat) { // newAndSave -> proxy/socstat.js
if (err) {
return next(err);
}
});
//** End : NewAndSave
}
/* END SAVES DATA TO MONGODB */

/* GET DATA FROM REDDIT API */
const reddit = new nodeSocialApi.Reddit(); // no auth needed

async function redditGet() {
let result;

await reddit.get('r/about/about.json')
.then((data) => {

// callback value for promise
result = data.data.subscribers;
saveToDb("reddit",result);

}) // end then
.catch(err => console.log(err));

return result;
}
/* END : GET DATA FROM REDDIT API */

/* REDDIT PROMISE (all the others look the same) */
function redditPromise() {
return new Promise(resolve => {
resolve(redditGet());
});
}
/* END : REDDIT PROMISE (all the others look the same) */

/* ONE FUNCTION THAT WAITS FOR ALL PROMISED FUNCTIONS */
async function msg() {
const [a, b, c,d] = await Promise.all([githubPromise(), twitterPromise(), redditPromise(), facebookPromise()]);

console.log(a + " " + b + " " + c + d);
}
/* END: ONE FUNCTION THAT WAITS FOR ALL PROMISED FUNCTIONS */

msg();

}; // END exports

HMR HMR
Answer Source

The only function available in the code you posted is twitterPromise, I would suggest as Bergi to return promises:

/* SAVES DATA TO MONGODB */
const saveToDb = (website,total) =>
  //** Start : NewAndSave
  new Promise(
    (resolve,reject) =>
      Socstat.newAndSave(
        website, 
        total, 
        "random", 
        (err, socstat) => // newAndSave -> proxy/socstat.js
          (err)
            ? reject(err)
            : resolve(socstat)
      )
  )
  //** End : NewAndSave
/* END SAVES DATA TO MONGODB */

const redditGet = () => 
  //just return a promise:
  reddit.get('r/about/about.json')
  .then(
    data =>
      //got the data, save to db and return subscribers
      saveToDb("reddit",data.data.subscribers)
      .then(
        _ => data.data.subscribers
      )
  );
/* END : GET DATA FROM REDDIT API */

/* REDDIT PROMISE (all the others look the same) */
const twitterPromise = redditGet;

/* ONE FUNCTION THAT WAITS FOR ALL PROMISED FUNCTIONS */
const msg = () =>
  Promise.all([githubPromise(), twitterPromise(), redditPromise(), facebookPromise()])
/* END: ONE FUNCTION THAT WAITS FOR ALL PROMISED FUNCTIONS */

msg()
.then(
  results =>
    console.log("got resullts",results)
  ,reject =>
    console.error("rejected",reject)
);

If you understand promises you could investigate async await, it has an easier syntax for people used to sync script (try catch) but in the end it will return a promise.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download