0

I have an async method from a package module with a callback function. The method itself returns undefined.

I've very new to async coding and would like to be able to halt the execution of the program until a variable arrayWithData is assigned data from the callback method.

e.g.

let dataFiles = fs.etc   

function makeDataArray(dataFiles) {
   let arrayWithData = [];
   for (let dataFile in dataFiles) {
     package.magicMethodToParseData(dataFile, function(result){ //async method with callback
        arrayWithData.push(result) //happens later
     });
   }
   return arrayWithData; //This returns undefined
}

function doSomethingWithData(dataArray) {
   /* Doing Stuff with Data Array */
}

/* Broken Code with undefined */
doSomethingWithData( makeDataArray(dataFiles) );

I know I can just add the rest of my execution inside the callback function but want to avoid that and keep the code flat.

How can I wait for data to be assigned to the array and then continue execution?

Update: Added github tester project to showcase the full problem as the promise keeps getting rejected.. Github Link: https://github.com/Jonathan002/autofont.git

3
  • The array will contain multiple values. I updated the example to be more clear. Commented May 10, 2017 at 13:37
  • Thank you, and is dataFiles an array? Perhaps you meant to use for of instead of for in (for in is for iterating the keys of objects). Commented May 10, 2017 at 13:40
  • Take a look at this link for some interesting insight on the effect of loops on async javascript pluralsight.com/guides/front-end-javascript/… Commented May 10, 2017 at 13:49

2 Answers 2

1

You can return a Promise which contains the array using Promise.all. The parameter to Promise.all must be an array of promises, and it returns a promise of an array of values.

You can use it like this:

function makeDataArray(dataFiles) {
  return Promise.all(dataFiles.map(function (dataFile) {
    return new Promise(function (resolve, reject) {
      package.magicMethodToParseData(dataFile, function (error, result) {
        if (error) {
          reject(error);
        } else {
          resolve(result);
        }
      });
    });
  }));
}

makeDataArray(dataFiles)
  .then(doSomethingWithData)
  .catch(console.error);
Sign up to request clarification or add additional context in comments.

6 Comments

Hi 4castle, I've been trying to use your implementation of promises but have not been able to get the then statement to execute. I'm trying to make it work with this package and it's callback: npmjs.com/package/fontmachine
Ok, I've updated my answer so that it uses the error present in the callback of that API. If you need, you could also update your question with your actual code instead of the example code.
Thanks 4castle for the update and sorry I couldn't respond yesterday. I've been trying to work on the promise with the resolve nested inside the callback function like you have suggested but the promise keeps on getting rejected. I have produced a github tester project to showcase the exact scenario: github Link.
I'm having some trouble getting fontmachine to install, but what is the error that it reports when the promise rejects?
I updated the github project to include the node_modules if your having trouble getting fontmachine. As for the error it uses the callback error from fontmachine Error: could not open font file on reject. However the callback will eventually retrieve the font files and I have logged the list. Once the font files are retrieved the if else statement has already executed and I'm having trouble halting the if-else to wait for it.
|
0

Hi Jonathan this is a very common scenario with async programming. You can use native promises with es6 or us a promise library such as bluebird or q. Here is a code example

   function someAsyncFunction() {
       // return promise here 
   }

  const promiseArray = [];

  // some random loop 
  for(let i = 0; i < 5; i++) {
  promiseArray.push(someAsyncFunction());

}
 Promise.all(promiseArray).then((results)=> {
 // resolved promises
console.log(results);
}).catch((error) => {
  console.log('errors ', errors);
})

If you need a good understanding of how promises work you can read the Promise documentation on MDN

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.