Using async/await with a forEach loop












595















Are there any issues with using async/await in a forEach loop? I'm trying to loop through an array of files and await on the contents of each file.



import fs from 'fs-promise'

async function printFiles () {
const files = await getFilePaths() // Assume this works fine

files.forEach(async (file) => {
const contents = await fs.readFile(file, 'utf8')
console.log(contents)
})
}

printFiles()


This code does work, but could something go wrong with this? I had someone tell me that you're not supposed to use async/await in a higher order function like this so I just wanted to ask if there was any issue with this.










share|improve this question





























    595















    Are there any issues with using async/await in a forEach loop? I'm trying to loop through an array of files and await on the contents of each file.



    import fs from 'fs-promise'

    async function printFiles () {
    const files = await getFilePaths() // Assume this works fine

    files.forEach(async (file) => {
    const contents = await fs.readFile(file, 'utf8')
    console.log(contents)
    })
    }

    printFiles()


    This code does work, but could something go wrong with this? I had someone tell me that you're not supposed to use async/await in a higher order function like this so I just wanted to ask if there was any issue with this.










    share|improve this question



























      595












      595








      595


      224






      Are there any issues with using async/await in a forEach loop? I'm trying to loop through an array of files and await on the contents of each file.



      import fs from 'fs-promise'

      async function printFiles () {
      const files = await getFilePaths() // Assume this works fine

      files.forEach(async (file) => {
      const contents = await fs.readFile(file, 'utf8')
      console.log(contents)
      })
      }

      printFiles()


      This code does work, but could something go wrong with this? I had someone tell me that you're not supposed to use async/await in a higher order function like this so I just wanted to ask if there was any issue with this.










      share|improve this question
















      Are there any issues with using async/await in a forEach loop? I'm trying to loop through an array of files and await on the contents of each file.



      import fs from 'fs-promise'

      async function printFiles () {
      const files = await getFilePaths() // Assume this works fine

      files.forEach(async (file) => {
      const contents = await fs.readFile(file, 'utf8')
      console.log(contents)
      })
      }

      printFiles()


      This code does work, but could something go wrong with this? I had someone tell me that you're not supposed to use async/await in a higher order function like this so I just wanted to ask if there was any issue with this.







      javascript node.js promise async-await ecmascript-2017






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 8 '17 at 17:20







      saadq

















      asked Jun 1 '16 at 18:55









      saadqsaadq

      10.1k93673




      10.1k93673
























          13 Answers
          13






          active

          oldest

          votes


















          1212














          Sure the code does work, but I'm pretty sure it doesn't do what you expect it to do. It just fires off multiple asynchronous calls, but the printFiles function does immediately return after that.



          If you want to read the files in sequence, you cannot use forEach indeed. Just use a modern for … of loop instead, in which await will work as expected:



          async function printFiles () {
          const files = await getFilePaths();

          for (const file of files) {
          const contents = await fs.readFile(file, 'utf8');
          console.log(contents);
          }
          }


          If you want to read the files in parallel, you cannot use forEach indeed. Each of the async callback function calls does return a promise, but you're throwing them away instead of awaiting them. Just use map instead, and you can await the array of promises that you'll get with Promise.all:



          async function printFiles () {
          const files = await getFilePaths();

          await Promise.all(files.map(async (file) => {
          const contents = await fs.readFile(file, 'utf8')
          console.log(contents)
          }));
          }





          share|improve this answer





















          • 14





            Could you please explain why does for ... of ... work?

            – Demonbane
            Aug 15 '16 at 18:04






          • 42





            ok i know why... Using Babel will transform async/await to generator function and using forEach means that each iteration has an individual generator function, which has nothing to do with the others. so they will be executed independently and has no context of next() with others. Actually, a simple for() loop also works because the iterations are also in one single generator function.

            – Demonbane
            Aug 15 '16 at 19:21








          • 12





            @Demonbane: In short, because it was designed to work :-) await suspends the current function evaluation, including all control structures. Yes, it is quite similar to generators in that regard (which is why they are used to polyfill async/await).

            – Bergi
            Aug 15 '16 at 23:28






          • 2





            @arve0 Not really, an async function is quite different from a Promise executor callback, but yes the map callback returns a promise in both cases.

            – Bergi
            Mar 29 '17 at 16:25






          • 2





            When you come to learn about JS promises, but instead use half an hour translating latin. Hope you're proud @Bergi ;)

            – Félix Gagnon-Grenier
            May 16 '17 at 21:04





















          89














          With ES2018, you are able to greatly simplify all of the above answers to:



          async function printFiles () {
          const files = await getFilePaths()

          for await (const file of fs.readFile(file, 'utf8')) {
          console.log(contents)
          }
          }


          See spec: https://github.com/tc39/proposal-async-iteration





          2018-09-10: This answer has been getting a lot attention recently, please see Axel Rauschmayer's blog post for further information about asynchronous iteration: http://2ality.com/2016/10/asynchronous-iteration.html






          share|improve this answer





















          • 3





            Upvoted, would be great if you could put a link to the spec in your answer for anyone who wants to know more about async iteration.

            – saadq
            Jun 15 '18 at 16:40






          • 3





            Where is file defined in your code?

            – ma11hew28
            Sep 3 '18 at 7:12






          • 1





            Shouldn't it be contents instead of file in the iterator

            – zeion
            Sep 18 '18 at 21:11








          • 2





            Why people are upvoting this answer? Take a closer look at the answer, question, and proposal. After the of should be the async function which will return an array. It doesn't work and Francisco said;

            – Yevhenii Herasymchuk
            Jan 8 at 16:27






          • 1





            I don't think this answer address the initial question. for-await-of with a synchronous iterable (an array in our case) doesn’t cover the case of iterating concurrently an array using asynchronous operations in each iteration. If I'm not mistaken, using for-await-of with a synchronous iterable over non-promise values is the same as using a plain for-of.

            – Antonio Val
            Jan 9 at 10:30



















          23














          To me using Promise.all() with map() is a bit difficult to understand and verbose, but if you want to do it in plain JS that's your best shot I guess.



          If you don't mind adding a module, I implemented the Array iteration methods so they can be used in a very straightforward way with async/await.



          An example with your case:



          const { forEach } = require('p-iteration');
          const fs = require('fs-promise');

          async function printFiles () {
          const files = await getFilePaths();

          await forEach(files, async (file) => {
          const contents = await fs.readFile(file, 'utf8');
          console.log(contents);
          });
          }

          printFiles()


          p-iteration






          share|improve this answer





















          • 1





            I like this as it has the same functions / methods as JS itself - in my case I needed some rather than forEach. Thanks!

            – mikemaccana
            Nov 14 '18 at 11:49



















          22
















          Instead of Promise.all in conjunction with Array.prototype.map (which does not guarantee the order in which the Promises are resolved), I use Array.prototype.reduce, starting with a resolved Promise:



          async function printFiles () {
          const files = await getFilePaths();

          await files.reduce(async (promise, file) => {
          // This line will wait for the last async function to finish.
          // The first iteration uses an already resolved Promise
          // so, it will immediately continue.
          await promise;
          const contents = await fs.readFile(file, 'utf8');
          console.log(contents);
          }, Promise.resolve());
          }





          share|improve this answer





















          • 1





            This works perfectly, thank you so much. Could you explain what is happening here with Promise.resolve() and await promise;?

            – parrker9
            Mar 28 '18 at 20:48






          • 1





            This is pretty cool. Am I right in thinking the files will be read in order and not all at once?

            – GollyJer
            Jun 9 '18 at 0:24






          • 1





            @parrker9 Promise.resolve() returns an already resolved Promise object, so that reduce has a Promise to start with. await promise; will wait for the last Promise in the chain to resolve. @GollyJer The files will be processed sequentially, one at a time.

            – Timothy Zorn
            Jun 17 '18 at 15:00





















          11














          Here are some forEach async prototypes:



          Array.prototype.forEachAsync = async function (fn) {
          for (let t of this) { await fn(t) }
          }

          Array.prototype.forEachAsyncParallel = async function (fn) {
          await Promise.all(this.map(fn));
          }





          share|improve this answer



















          • 1





            Although I'd hesitate to add things directly to the prototype, this is a nice async forEach implementation

            – DaniOcean
            Mar 28 '18 at 13:55











          • As long as the name is unique in the future (like I'd use _forEachAsync) this is reasonable. I also think it's the nicest answer as it saves a lot of boilerplate code.

            – mikemaccana
            Apr 3 '18 at 13:29











          • They should be standalone functions. We've got modules to not pollute globals with our personal things.

            – estus
            Nov 5 '18 at 6:25



















          2














          Both the solutions above work, however, Antonio's does the job with less code, here is how it helped me resolve data from my database, from several different child refs and then pushing them all into an array and resolving it in a promise after all is done:



          Promise.all(PacksList.map((pack)=>{
          return fireBaseRef.child(pack.folderPath).once('value',(snap)=>{
          snap.forEach( childSnap => {
          const file = childSnap.val()
          file.id = childSnap.key;
          allItems.push( file )
          })
          })
          })).then(()=>store.dispatch( actions.allMockupItems(allItems)))





          share|improve this answer































            2














            it's pretty painless to pop a couple methods in a file that will handle asynchronous data in a serialized order and give a more conventional flavour to your code. For example:



            module.exports = function () {
            var self = this;

            this.each = async (items, fn) => {
            if (items && items.length) {
            await Promise.all(
            items.map(async (item) => {
            await fn(item);
            }));
            }
            };

            this.reduce = async (items, fn, initialValue) => {
            await self.each(
            items, async (item) => {
            initialValue = await fn(initialValue, item);
            });
            return initialValue;
            };
            };


            now, assuming that's saved at './myAsync.js' you can do something similar to the below in an adjacent file:



            ...
            /* your server setup here */
            ...
            var MyAsync = require('./myAsync');
            var Cat = require('./models/Cat');
            var Doje = require('./models/Doje');
            var example = async () => {
            var myAsync = new MyAsync();
            var doje = await Doje.findOne({ name: 'Doje', noises: }).save();
            var cleanParams = ;

            // FOR EACH EXAMPLE
            await myAsync.each(['bork', 'concern', 'heck'],
            async (elem) => {
            if (elem !== 'heck') {
            await doje.update({ $push: { 'noises': elem }});
            }
            });

            var cat = await Cat.findOne({ name: 'Nyan' });

            // REDUCE EXAMPLE
            var friendsOfNyanCat = await myAsync.reduce(cat.friends,
            async (catArray, friendId) => {
            var friend = await Friend.findById(friendId);
            if (friend.name !== 'Long cat') {
            catArray.push(friend.name);
            }
            }, );
            // Assuming Long Cat was a friend of Nyan Cat...
            assert(friendsOfNyanCat.length === (cat.friends.length - 1));
            }





            share|improve this answer





















            • 2





              Minor addendum, don't forget to wrap your await/asyncs in try/catch blocks!!

              – Jay Edwards
              Sep 26 '17 at 9:08



















            1














            Using Task, futurize, and a traversable List, you can simply do



            async function printFiles() {
            const files = await getFiles();

            List(files).traverse( Task.of, f => readFile( f, 'utf-8'))
            .fork( console.error, console.log)
            }


            Here is how you'd set this up



            import fs from 'fs';
            import { futurize } from 'futurize';
            import Task from 'data.task';
            import { List } from 'immutable-ext';

            const future = futurizeP(Task)
            const readFile = future(fs.readFile)


            Another way to have structured the desired code would be



            const printFiles = files => 
            List(files).traverse( Task.of, fn => readFile( fn, 'utf-8'))
            .fork( console.error, console.log)


            Or perhaps even more functionally oriented



            // 90% of encodings are utf-8, making that use case super easy is prudent

            // handy-library.js
            export const readFile = f =>
            future(fs.readFile)( f, 'utf-8' )

            export const arrayToTaskList = list => taskFn =>
            List(files).traverse( Task.of, taskFn )

            export const readFiles = files =>
            arrayToTaskList( files, readFile )

            export const printFiles = files =>
            readFiles(files).fork( console.error, console.log)


            Then from the parent function



            async function main() {
            /* awesome code with side-effects before */
            printFiles( await getFiles() );
            /* awesome code with side-effects after */
            }


            If you really wanted more flexibility in encoding, you could just do this (for fun, I'm using the proposed Pipe Forward operator )



            import { curry, flip } from 'ramda'

            export const readFile = fs.readFile
            |> future,
            |> curry,
            |> flip

            export const readFileUtf8 = readFile('utf-8')


            PS - I didn't try this code on the console, might have some typos... "straight freestyle, off the top of the dome!" as the 90s kids would say. :-p






            share|improve this answer

































              1














              In addition to @Bergi’s answer, I’d like to offer a third alternative. It's very similar to @Bergi’s 2nd example, but instead of awaiting each readFile individually, you create an array of promises, each which you await at the end.



              import fs from 'fs-promise';
              async function printFiles () {
              const files = await getFilePaths();

              const promises = files.map((file) => fs.readFile(file, 'utf8'))

              const contents = await Promise.all(promises)

              contents.forEach(console.log);
              }


              Note that the function passed to .map() does not need to be async, since fs.readFile returns a Promise object anyway. Therefore promises is an array of Promise objects, which can be sent to Promise.all().



              In @Bergi’s answer, the console may log file contents out of order. For example if a really small file finishes reading before a really large file, it will be logged first, even if the small file comes after the large file in the files array. However, in my method above, you are guaranteed the console will log the files in the same order as they are read.






              share|improve this answer

































                0














                One important caveat is: The await + for .. of method and the forEach + async way actually have different effect.



                Having await inside a real for loop will make sure all async calls are executed one by one. And the forEach + async way will fire off all promises at the same time, which is faster but sometimes overwhelmed(if you do some DB query or visit some web services with volume restrictions and do not want to fire 100,000 calls at a time).



                You can also use reduce + promise(less elegant) if you do not use async/await and want to make sure files are read one after another.



                files.reduce((lastPromise, file) => 
                lastPromise.then(() =>
                fs.readFile(file, 'utf8')
                ), Promise.resolve()
                )


                Or you can create a forEachAsync to help but basically use the same for loop underlying.



                Array.prototype.forEachAsync = async function(cb){
                for(let x of this){
                await cb(x);
                }
                }





                share|improve this answer
























                • Have a look at How to define method in javascript on Array.prototype and Object.prototype so that it doesn't appear in for in loop. Also you probably should use the same iteration as native forEach - accessing indices instead of relying on iterability - and pass the index to the callback.

                  – Bergi
                  Nov 16 '17 at 13:57











                • You can use Array.prototype.reduce in a way that uses an async function. I've shown an example in my answer: stackoverflow.com/a/49499491/2537258

                  – Timothy Zorn
                  Mar 26 '18 at 19:54



















                0














                Similar to Antonio Val's p-iteration, an alternative npm module is async-af:



                const AsyncAF = require('async-af');
                const fs = require('fs-promise');

                function printFiles() {
                // since AsyncAF accepts promises or non-promises, there's no need to await here
                const files = getFilePaths();

                AsyncAF(files).forEach(async file => {
                const contents = await fs.readFile(file, 'utf8');
                console.log(contents);
                });
                }

                printFiles();


                Alternatively, async-af has a static method (log/logAF) that logs the results of promises:



                const AsyncAF = require('async-af');
                const fs = require('fs-promise');

                function printFiles() {
                const files = getFilePaths();

                AsyncAF(files).forEach(file => {
                AsyncAF.log(fs.readFile(file, 'utf8'));
                });
                }

                printFiles();


                However, the main advantage of the library is that you can chain asynchronous methods to do something like:



                const aaf = require('async-af');
                const fs = require('fs-promise');

                const printFiles = () => aaf(getFilePaths())
                .map(file => fs.readFile(file, 'utf8'))
                .forEach(file => aaf.log(file));

                printFiles();


                async-af






                share|improve this answer































                  0














                  Currently the Array.forEach prototype property doesn't support async operations, but we can create our own poly-fill to meet our needs.



                  // Example of asyncForEach Array poly-fill for NodeJs
                  // file: asyncForEach.js
                  // Define asynForEach function
                  async function asyncForEach(callback){
                  let indexer = 0
                  for(let data of this){
                  await callback(data, indexer)
                  indexer++
                  }
                  }
                  // Append it as an Array prototype property
                  Array.prototype.asyncForEach = asyncForEach
                  module.exports = {Array}


                  And that's it! You now have an async forEach method available on any arrays that are defined after these to operations.



                  Let's test it...



                  // Nodejs style
                  // file: someOtherFile.js

                  const readline = require('readline')
                  Array = require('./asyncForEach').Array
                  const log = console.log

                  // Create a stream interface
                  function createReader(options={prompt: '>'}){
                  return readline.createInterface({
                  input: process.stdin
                  ,output: process.stdout
                  ,prompt: options.prompt !== undefined ? options.prompt : '>'
                  })
                  }
                  // Create a cli stream reader
                  async function getUserIn(question, options={prompt:'>'}){
                  log(question)
                  let reader = createReader(options)
                  return new Promise((res)=>{
                  reader.on('line', (answer)=>{
                  process.stdout.cursorTo(0, 0)
                  process.stdout.clearScreenDown()
                  reader.close()
                  res(answer)
                  })
                  })
                  }

                  let questions = [
                  `What's your name`
                  ,`What's your favorite programming language`
                  ,`What's your favorite async function`
                  ]
                  let responses = {}

                  async function getResponses(){
                  // Notice we have to prepend await before calling the async Array function
                  // in order for it to function as expected
                  await questions.asyncForEach(async function(question, index){
                  let answer = await getUserIn(question)
                  responses[question] = answer
                  })
                  }

                  async function main(){
                  await getResponses()
                  log(responses)
                  }
                  main()
                  // Should prompt user for an answer to each question and then
                  // log each question and answer as an object to the terminal


                  We could do the same for some of the other array functions like map...



                  async function asyncMap(callback){
                  let newMap =
                  let indexer = 0
                  for(let data of this){
                  newMap[indexer] = await callback(data, indexer, this)
                  indexer++
                  }
                  return newMap
                  }

                  Array.prototype.asyncMap = asyncMap


                  ... and so on :)



                  Some things to note:




                  • Your callback must be an async function or promise

                  • Any arrays created before Array.prototype.<yourAsyncFunc> = <yourAsyncFunc> will not have this feature available






                  share|improve this answer































                    -3














                    I would use the well-tested (millions of downloads per week) pify and async modules. If you are unfamiliar with the async module, I highly recommend you check out its docs. I've seen multiple devs waste time recreating its methods, or worse, making difficult-to-maintain async code when higher-order async methods would simplify code.






                    const async = require('async')
                    const fs = require('fs-promise')
                    const pify = require('pify')

                    async function getFilePaths() {
                    return Promise.resolve([
                    './package.json',
                    './package-lock.json',
                    ]);
                    }

                    async function printFiles () {
                    const files = await getFilePaths()

                    await pify(async.eachSeries)(files, async (file) => { // <-- run in series
                    // await pify(async.each)(files, async (file) => { // <-- run in parallel
                    const contents = await fs.readFile(file, 'utf8')
                    console.log(contents)
                    })
                    console.log('HAMBONE')
                    }

                    printFiles().then(() => {
                    console.log('HAMBUNNY')
                    })
                    // ORDER OF LOGS:
                    // package.json contents
                    // package-lock.json contents
                    // HAMBONE
                    // HAMBUNNY
                    ```








                    share|improve this answer
























                    • This is a step in the wrong direction. Here's a mapping guide I created to help get folks stuck in callback hell into the modern JS era: github.com/jmjpro/async-package-to-async-await/blob/master/….

                      – jbustamovej
                      Feb 20 '18 at 6:24











                    • as you can see here, I am interested in and open to using async/await instead of the async lib. Right now, I think that each has a time and place. I'm not convinced that the async lib == "callback hell" and async/await == "the modern JS era". imo, when async lib > async/await: 1. complex flow (eg, queue, cargo, even auto when things get complicated) 2. concurrency 3. supporting arrays/objects/iterables 4. err handling

                      – Zachary Ryan Smith
                      Feb 21 '18 at 1:54










                    protected by georgeawg Aug 16 '18 at 17:41



                    Thank you for your interest in this question.
                    Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                    Would you like to answer one of these unanswered questions instead?














                    13 Answers
                    13






                    active

                    oldest

                    votes








                    13 Answers
                    13






                    active

                    oldest

                    votes









                    active

                    oldest

                    votes






                    active

                    oldest

                    votes









                    1212














                    Sure the code does work, but I'm pretty sure it doesn't do what you expect it to do. It just fires off multiple asynchronous calls, but the printFiles function does immediately return after that.



                    If you want to read the files in sequence, you cannot use forEach indeed. Just use a modern for … of loop instead, in which await will work as expected:



                    async function printFiles () {
                    const files = await getFilePaths();

                    for (const file of files) {
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    }
                    }


                    If you want to read the files in parallel, you cannot use forEach indeed. Each of the async callback function calls does return a promise, but you're throwing them away instead of awaiting them. Just use map instead, and you can await the array of promises that you'll get with Promise.all:



                    async function printFiles () {
                    const files = await getFilePaths();

                    await Promise.all(files.map(async (file) => {
                    const contents = await fs.readFile(file, 'utf8')
                    console.log(contents)
                    }));
                    }





                    share|improve this answer





















                    • 14





                      Could you please explain why does for ... of ... work?

                      – Demonbane
                      Aug 15 '16 at 18:04






                    • 42





                      ok i know why... Using Babel will transform async/await to generator function and using forEach means that each iteration has an individual generator function, which has nothing to do with the others. so they will be executed independently and has no context of next() with others. Actually, a simple for() loop also works because the iterations are also in one single generator function.

                      – Demonbane
                      Aug 15 '16 at 19:21








                    • 12





                      @Demonbane: In short, because it was designed to work :-) await suspends the current function evaluation, including all control structures. Yes, it is quite similar to generators in that regard (which is why they are used to polyfill async/await).

                      – Bergi
                      Aug 15 '16 at 23:28






                    • 2





                      @arve0 Not really, an async function is quite different from a Promise executor callback, but yes the map callback returns a promise in both cases.

                      – Bergi
                      Mar 29 '17 at 16:25






                    • 2





                      When you come to learn about JS promises, but instead use half an hour translating latin. Hope you're proud @Bergi ;)

                      – Félix Gagnon-Grenier
                      May 16 '17 at 21:04


















                    1212














                    Sure the code does work, but I'm pretty sure it doesn't do what you expect it to do. It just fires off multiple asynchronous calls, but the printFiles function does immediately return after that.



                    If you want to read the files in sequence, you cannot use forEach indeed. Just use a modern for … of loop instead, in which await will work as expected:



                    async function printFiles () {
                    const files = await getFilePaths();

                    for (const file of files) {
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    }
                    }


                    If you want to read the files in parallel, you cannot use forEach indeed. Each of the async callback function calls does return a promise, but you're throwing them away instead of awaiting them. Just use map instead, and you can await the array of promises that you'll get with Promise.all:



                    async function printFiles () {
                    const files = await getFilePaths();

                    await Promise.all(files.map(async (file) => {
                    const contents = await fs.readFile(file, 'utf8')
                    console.log(contents)
                    }));
                    }





                    share|improve this answer





















                    • 14





                      Could you please explain why does for ... of ... work?

                      – Demonbane
                      Aug 15 '16 at 18:04






                    • 42





                      ok i know why... Using Babel will transform async/await to generator function and using forEach means that each iteration has an individual generator function, which has nothing to do with the others. so they will be executed independently and has no context of next() with others. Actually, a simple for() loop also works because the iterations are also in one single generator function.

                      – Demonbane
                      Aug 15 '16 at 19:21








                    • 12





                      @Demonbane: In short, because it was designed to work :-) await suspends the current function evaluation, including all control structures. Yes, it is quite similar to generators in that regard (which is why they are used to polyfill async/await).

                      – Bergi
                      Aug 15 '16 at 23:28






                    • 2





                      @arve0 Not really, an async function is quite different from a Promise executor callback, but yes the map callback returns a promise in both cases.

                      – Bergi
                      Mar 29 '17 at 16:25






                    • 2





                      When you come to learn about JS promises, but instead use half an hour translating latin. Hope you're proud @Bergi ;)

                      – Félix Gagnon-Grenier
                      May 16 '17 at 21:04
















                    1212












                    1212








                    1212







                    Sure the code does work, but I'm pretty sure it doesn't do what you expect it to do. It just fires off multiple asynchronous calls, but the printFiles function does immediately return after that.



                    If you want to read the files in sequence, you cannot use forEach indeed. Just use a modern for … of loop instead, in which await will work as expected:



                    async function printFiles () {
                    const files = await getFilePaths();

                    for (const file of files) {
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    }
                    }


                    If you want to read the files in parallel, you cannot use forEach indeed. Each of the async callback function calls does return a promise, but you're throwing them away instead of awaiting them. Just use map instead, and you can await the array of promises that you'll get with Promise.all:



                    async function printFiles () {
                    const files = await getFilePaths();

                    await Promise.all(files.map(async (file) => {
                    const contents = await fs.readFile(file, 'utf8')
                    console.log(contents)
                    }));
                    }





                    share|improve this answer















                    Sure the code does work, but I'm pretty sure it doesn't do what you expect it to do. It just fires off multiple asynchronous calls, but the printFiles function does immediately return after that.



                    If you want to read the files in sequence, you cannot use forEach indeed. Just use a modern for … of loop instead, in which await will work as expected:



                    async function printFiles () {
                    const files = await getFilePaths();

                    for (const file of files) {
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    }
                    }


                    If you want to read the files in parallel, you cannot use forEach indeed. Each of the async callback function calls does return a promise, but you're throwing them away instead of awaiting them. Just use map instead, and you can await the array of promises that you'll get with Promise.all:



                    async function printFiles () {
                    const files = await getFilePaths();

                    await Promise.all(files.map(async (file) => {
                    const contents = await fs.readFile(file, 'utf8')
                    console.log(contents)
                    }));
                    }






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jul 1 '18 at 21:50









                    Joshua Pinter

                    25k9142171




                    25k9142171










                    answered Jun 1 '16 at 19:02









                    BergiBergi

                    378k63576905




                    378k63576905








                    • 14





                      Could you please explain why does for ... of ... work?

                      – Demonbane
                      Aug 15 '16 at 18:04






                    • 42





                      ok i know why... Using Babel will transform async/await to generator function and using forEach means that each iteration has an individual generator function, which has nothing to do with the others. so they will be executed independently and has no context of next() with others. Actually, a simple for() loop also works because the iterations are also in one single generator function.

                      – Demonbane
                      Aug 15 '16 at 19:21








                    • 12





                      @Demonbane: In short, because it was designed to work :-) await suspends the current function evaluation, including all control structures. Yes, it is quite similar to generators in that regard (which is why they are used to polyfill async/await).

                      – Bergi
                      Aug 15 '16 at 23:28






                    • 2





                      @arve0 Not really, an async function is quite different from a Promise executor callback, but yes the map callback returns a promise in both cases.

                      – Bergi
                      Mar 29 '17 at 16:25






                    • 2





                      When you come to learn about JS promises, but instead use half an hour translating latin. Hope you're proud @Bergi ;)

                      – Félix Gagnon-Grenier
                      May 16 '17 at 21:04
















                    • 14





                      Could you please explain why does for ... of ... work?

                      – Demonbane
                      Aug 15 '16 at 18:04






                    • 42





                      ok i know why... Using Babel will transform async/await to generator function and using forEach means that each iteration has an individual generator function, which has nothing to do with the others. so they will be executed independently and has no context of next() with others. Actually, a simple for() loop also works because the iterations are also in one single generator function.

                      – Demonbane
                      Aug 15 '16 at 19:21








                    • 12





                      @Demonbane: In short, because it was designed to work :-) await suspends the current function evaluation, including all control structures. Yes, it is quite similar to generators in that regard (which is why they are used to polyfill async/await).

                      – Bergi
                      Aug 15 '16 at 23:28






                    • 2





                      @arve0 Not really, an async function is quite different from a Promise executor callback, but yes the map callback returns a promise in both cases.

                      – Bergi
                      Mar 29 '17 at 16:25






                    • 2





                      When you come to learn about JS promises, but instead use half an hour translating latin. Hope you're proud @Bergi ;)

                      – Félix Gagnon-Grenier
                      May 16 '17 at 21:04










                    14




                    14





                    Could you please explain why does for ... of ... work?

                    – Demonbane
                    Aug 15 '16 at 18:04





                    Could you please explain why does for ... of ... work?

                    – Demonbane
                    Aug 15 '16 at 18:04




                    42




                    42





                    ok i know why... Using Babel will transform async/await to generator function and using forEach means that each iteration has an individual generator function, which has nothing to do with the others. so they will be executed independently and has no context of next() with others. Actually, a simple for() loop also works because the iterations are also in one single generator function.

                    – Demonbane
                    Aug 15 '16 at 19:21







                    ok i know why... Using Babel will transform async/await to generator function and using forEach means that each iteration has an individual generator function, which has nothing to do with the others. so they will be executed independently and has no context of next() with others. Actually, a simple for() loop also works because the iterations are also in one single generator function.

                    – Demonbane
                    Aug 15 '16 at 19:21






                    12




                    12





                    @Demonbane: In short, because it was designed to work :-) await suspends the current function evaluation, including all control structures. Yes, it is quite similar to generators in that regard (which is why they are used to polyfill async/await).

                    – Bergi
                    Aug 15 '16 at 23:28





                    @Demonbane: In short, because it was designed to work :-) await suspends the current function evaluation, including all control structures. Yes, it is quite similar to generators in that regard (which is why they are used to polyfill async/await).

                    – Bergi
                    Aug 15 '16 at 23:28




                    2




                    2





                    @arve0 Not really, an async function is quite different from a Promise executor callback, but yes the map callback returns a promise in both cases.

                    – Bergi
                    Mar 29 '17 at 16:25





                    @arve0 Not really, an async function is quite different from a Promise executor callback, but yes the map callback returns a promise in both cases.

                    – Bergi
                    Mar 29 '17 at 16:25




                    2




                    2





                    When you come to learn about JS promises, but instead use half an hour translating latin. Hope you're proud @Bergi ;)

                    – Félix Gagnon-Grenier
                    May 16 '17 at 21:04







                    When you come to learn about JS promises, but instead use half an hour translating latin. Hope you're proud @Bergi ;)

                    – Félix Gagnon-Grenier
                    May 16 '17 at 21:04















                    89














                    With ES2018, you are able to greatly simplify all of the above answers to:



                    async function printFiles () {
                    const files = await getFilePaths()

                    for await (const file of fs.readFile(file, 'utf8')) {
                    console.log(contents)
                    }
                    }


                    See spec: https://github.com/tc39/proposal-async-iteration





                    2018-09-10: This answer has been getting a lot attention recently, please see Axel Rauschmayer's blog post for further information about asynchronous iteration: http://2ality.com/2016/10/asynchronous-iteration.html






                    share|improve this answer





















                    • 3





                      Upvoted, would be great if you could put a link to the spec in your answer for anyone who wants to know more about async iteration.

                      – saadq
                      Jun 15 '18 at 16:40






                    • 3





                      Where is file defined in your code?

                      – ma11hew28
                      Sep 3 '18 at 7:12






                    • 1





                      Shouldn't it be contents instead of file in the iterator

                      – zeion
                      Sep 18 '18 at 21:11








                    • 2





                      Why people are upvoting this answer? Take a closer look at the answer, question, and proposal. After the of should be the async function which will return an array. It doesn't work and Francisco said;

                      – Yevhenii Herasymchuk
                      Jan 8 at 16:27






                    • 1





                      I don't think this answer address the initial question. for-await-of with a synchronous iterable (an array in our case) doesn’t cover the case of iterating concurrently an array using asynchronous operations in each iteration. If I'm not mistaken, using for-await-of with a synchronous iterable over non-promise values is the same as using a plain for-of.

                      – Antonio Val
                      Jan 9 at 10:30
















                    89














                    With ES2018, you are able to greatly simplify all of the above answers to:



                    async function printFiles () {
                    const files = await getFilePaths()

                    for await (const file of fs.readFile(file, 'utf8')) {
                    console.log(contents)
                    }
                    }


                    See spec: https://github.com/tc39/proposal-async-iteration





                    2018-09-10: This answer has been getting a lot attention recently, please see Axel Rauschmayer's blog post for further information about asynchronous iteration: http://2ality.com/2016/10/asynchronous-iteration.html






                    share|improve this answer





















                    • 3





                      Upvoted, would be great if you could put a link to the spec in your answer for anyone who wants to know more about async iteration.

                      – saadq
                      Jun 15 '18 at 16:40






                    • 3





                      Where is file defined in your code?

                      – ma11hew28
                      Sep 3 '18 at 7:12






                    • 1





                      Shouldn't it be contents instead of file in the iterator

                      – zeion
                      Sep 18 '18 at 21:11








                    • 2





                      Why people are upvoting this answer? Take a closer look at the answer, question, and proposal. After the of should be the async function which will return an array. It doesn't work and Francisco said;

                      – Yevhenii Herasymchuk
                      Jan 8 at 16:27






                    • 1





                      I don't think this answer address the initial question. for-await-of with a synchronous iterable (an array in our case) doesn’t cover the case of iterating concurrently an array using asynchronous operations in each iteration. If I'm not mistaken, using for-await-of with a synchronous iterable over non-promise values is the same as using a plain for-of.

                      – Antonio Val
                      Jan 9 at 10:30














                    89












                    89








                    89







                    With ES2018, you are able to greatly simplify all of the above answers to:



                    async function printFiles () {
                    const files = await getFilePaths()

                    for await (const file of fs.readFile(file, 'utf8')) {
                    console.log(contents)
                    }
                    }


                    See spec: https://github.com/tc39/proposal-async-iteration





                    2018-09-10: This answer has been getting a lot attention recently, please see Axel Rauschmayer's blog post for further information about asynchronous iteration: http://2ality.com/2016/10/asynchronous-iteration.html






                    share|improve this answer















                    With ES2018, you are able to greatly simplify all of the above answers to:



                    async function printFiles () {
                    const files = await getFilePaths()

                    for await (const file of fs.readFile(file, 'utf8')) {
                    console.log(contents)
                    }
                    }


                    See spec: https://github.com/tc39/proposal-async-iteration





                    2018-09-10: This answer has been getting a lot attention recently, please see Axel Rauschmayer's blog post for further information about asynchronous iteration: http://2ality.com/2016/10/asynchronous-iteration.html







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Sep 10 '18 at 20:58

























                    answered Jun 15 '18 at 11:17









                    Francisco MateoFrancisco Mateo

                    4,28021531




                    4,28021531








                    • 3





                      Upvoted, would be great if you could put a link to the spec in your answer for anyone who wants to know more about async iteration.

                      – saadq
                      Jun 15 '18 at 16:40






                    • 3





                      Where is file defined in your code?

                      – ma11hew28
                      Sep 3 '18 at 7:12






                    • 1





                      Shouldn't it be contents instead of file in the iterator

                      – zeion
                      Sep 18 '18 at 21:11








                    • 2





                      Why people are upvoting this answer? Take a closer look at the answer, question, and proposal. After the of should be the async function which will return an array. It doesn't work and Francisco said;

                      – Yevhenii Herasymchuk
                      Jan 8 at 16:27






                    • 1





                      I don't think this answer address the initial question. for-await-of with a synchronous iterable (an array in our case) doesn’t cover the case of iterating concurrently an array using asynchronous operations in each iteration. If I'm not mistaken, using for-await-of with a synchronous iterable over non-promise values is the same as using a plain for-of.

                      – Antonio Val
                      Jan 9 at 10:30














                    • 3





                      Upvoted, would be great if you could put a link to the spec in your answer for anyone who wants to know more about async iteration.

                      – saadq
                      Jun 15 '18 at 16:40






                    • 3





                      Where is file defined in your code?

                      – ma11hew28
                      Sep 3 '18 at 7:12






                    • 1





                      Shouldn't it be contents instead of file in the iterator

                      – zeion
                      Sep 18 '18 at 21:11








                    • 2





                      Why people are upvoting this answer? Take a closer look at the answer, question, and proposal. After the of should be the async function which will return an array. It doesn't work and Francisco said;

                      – Yevhenii Herasymchuk
                      Jan 8 at 16:27






                    • 1





                      I don't think this answer address the initial question. for-await-of with a synchronous iterable (an array in our case) doesn’t cover the case of iterating concurrently an array using asynchronous operations in each iteration. If I'm not mistaken, using for-await-of with a synchronous iterable over non-promise values is the same as using a plain for-of.

                      – Antonio Val
                      Jan 9 at 10:30








                    3




                    3





                    Upvoted, would be great if you could put a link to the spec in your answer for anyone who wants to know more about async iteration.

                    – saadq
                    Jun 15 '18 at 16:40





                    Upvoted, would be great if you could put a link to the spec in your answer for anyone who wants to know more about async iteration.

                    – saadq
                    Jun 15 '18 at 16:40




                    3




                    3





                    Where is file defined in your code?

                    – ma11hew28
                    Sep 3 '18 at 7:12





                    Where is file defined in your code?

                    – ma11hew28
                    Sep 3 '18 at 7:12




                    1




                    1





                    Shouldn't it be contents instead of file in the iterator

                    – zeion
                    Sep 18 '18 at 21:11







                    Shouldn't it be contents instead of file in the iterator

                    – zeion
                    Sep 18 '18 at 21:11






                    2




                    2





                    Why people are upvoting this answer? Take a closer look at the answer, question, and proposal. After the of should be the async function which will return an array. It doesn't work and Francisco said;

                    – Yevhenii Herasymchuk
                    Jan 8 at 16:27





                    Why people are upvoting this answer? Take a closer look at the answer, question, and proposal. After the of should be the async function which will return an array. It doesn't work and Francisco said;

                    – Yevhenii Herasymchuk
                    Jan 8 at 16:27




                    1




                    1





                    I don't think this answer address the initial question. for-await-of with a synchronous iterable (an array in our case) doesn’t cover the case of iterating concurrently an array using asynchronous operations in each iteration. If I'm not mistaken, using for-await-of with a synchronous iterable over non-promise values is the same as using a plain for-of.

                    – Antonio Val
                    Jan 9 at 10:30





                    I don't think this answer address the initial question. for-await-of with a synchronous iterable (an array in our case) doesn’t cover the case of iterating concurrently an array using asynchronous operations in each iteration. If I'm not mistaken, using for-await-of with a synchronous iterable over non-promise values is the same as using a plain for-of.

                    – Antonio Val
                    Jan 9 at 10:30











                    23














                    To me using Promise.all() with map() is a bit difficult to understand and verbose, but if you want to do it in plain JS that's your best shot I guess.



                    If you don't mind adding a module, I implemented the Array iteration methods so they can be used in a very straightforward way with async/await.



                    An example with your case:



                    const { forEach } = require('p-iteration');
                    const fs = require('fs-promise');

                    async function printFiles () {
                    const files = await getFilePaths();

                    await forEach(files, async (file) => {
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    });
                    }

                    printFiles()


                    p-iteration






                    share|improve this answer





















                    • 1





                      I like this as it has the same functions / methods as JS itself - in my case I needed some rather than forEach. Thanks!

                      – mikemaccana
                      Nov 14 '18 at 11:49
















                    23














                    To me using Promise.all() with map() is a bit difficult to understand and verbose, but if you want to do it in plain JS that's your best shot I guess.



                    If you don't mind adding a module, I implemented the Array iteration methods so they can be used in a very straightforward way with async/await.



                    An example with your case:



                    const { forEach } = require('p-iteration');
                    const fs = require('fs-promise');

                    async function printFiles () {
                    const files = await getFilePaths();

                    await forEach(files, async (file) => {
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    });
                    }

                    printFiles()


                    p-iteration






                    share|improve this answer





















                    • 1





                      I like this as it has the same functions / methods as JS itself - in my case I needed some rather than forEach. Thanks!

                      – mikemaccana
                      Nov 14 '18 at 11:49














                    23












                    23








                    23







                    To me using Promise.all() with map() is a bit difficult to understand and verbose, but if you want to do it in plain JS that's your best shot I guess.



                    If you don't mind adding a module, I implemented the Array iteration methods so they can be used in a very straightforward way with async/await.



                    An example with your case:



                    const { forEach } = require('p-iteration');
                    const fs = require('fs-promise');

                    async function printFiles () {
                    const files = await getFilePaths();

                    await forEach(files, async (file) => {
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    });
                    }

                    printFiles()


                    p-iteration






                    share|improve this answer















                    To me using Promise.all() with map() is a bit difficult to understand and verbose, but if you want to do it in plain JS that's your best shot I guess.



                    If you don't mind adding a module, I implemented the Array iteration methods so they can be used in a very straightforward way with async/await.



                    An example with your case:



                    const { forEach } = require('p-iteration');
                    const fs = require('fs-promise');

                    async function printFiles () {
                    const files = await getFilePaths();

                    await forEach(files, async (file) => {
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    });
                    }

                    printFiles()


                    p-iteration







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Oct 16 '17 at 0:03

























                    answered Jul 10 '17 at 8:15









                    Antonio ValAntonio Val

                    1,6471419




                    1,6471419








                    • 1





                      I like this as it has the same functions / methods as JS itself - in my case I needed some rather than forEach. Thanks!

                      – mikemaccana
                      Nov 14 '18 at 11:49














                    • 1





                      I like this as it has the same functions / methods as JS itself - in my case I needed some rather than forEach. Thanks!

                      – mikemaccana
                      Nov 14 '18 at 11:49








                    1




                    1





                    I like this as it has the same functions / methods as JS itself - in my case I needed some rather than forEach. Thanks!

                    – mikemaccana
                    Nov 14 '18 at 11:49





                    I like this as it has the same functions / methods as JS itself - in my case I needed some rather than forEach. Thanks!

                    – mikemaccana
                    Nov 14 '18 at 11:49











                    22
















                    Instead of Promise.all in conjunction with Array.prototype.map (which does not guarantee the order in which the Promises are resolved), I use Array.prototype.reduce, starting with a resolved Promise:



                    async function printFiles () {
                    const files = await getFilePaths();

                    await files.reduce(async (promise, file) => {
                    // This line will wait for the last async function to finish.
                    // The first iteration uses an already resolved Promise
                    // so, it will immediately continue.
                    await promise;
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    }, Promise.resolve());
                    }





                    share|improve this answer





















                    • 1





                      This works perfectly, thank you so much. Could you explain what is happening here with Promise.resolve() and await promise;?

                      – parrker9
                      Mar 28 '18 at 20:48






                    • 1





                      This is pretty cool. Am I right in thinking the files will be read in order and not all at once?

                      – GollyJer
                      Jun 9 '18 at 0:24






                    • 1





                      @parrker9 Promise.resolve() returns an already resolved Promise object, so that reduce has a Promise to start with. await promise; will wait for the last Promise in the chain to resolve. @GollyJer The files will be processed sequentially, one at a time.

                      – Timothy Zorn
                      Jun 17 '18 at 15:00


















                    22
















                    Instead of Promise.all in conjunction with Array.prototype.map (which does not guarantee the order in which the Promises are resolved), I use Array.prototype.reduce, starting with a resolved Promise:



                    async function printFiles () {
                    const files = await getFilePaths();

                    await files.reduce(async (promise, file) => {
                    // This line will wait for the last async function to finish.
                    // The first iteration uses an already resolved Promise
                    // so, it will immediately continue.
                    await promise;
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    }, Promise.resolve());
                    }





                    share|improve this answer





















                    • 1





                      This works perfectly, thank you so much. Could you explain what is happening here with Promise.resolve() and await promise;?

                      – parrker9
                      Mar 28 '18 at 20:48






                    • 1





                      This is pretty cool. Am I right in thinking the files will be read in order and not all at once?

                      – GollyJer
                      Jun 9 '18 at 0:24






                    • 1





                      @parrker9 Promise.resolve() returns an already resolved Promise object, so that reduce has a Promise to start with. await promise; will wait for the last Promise in the chain to resolve. @GollyJer The files will be processed sequentially, one at a time.

                      – Timothy Zorn
                      Jun 17 '18 at 15:00
















                    22












                    22








                    22









                    Instead of Promise.all in conjunction with Array.prototype.map (which does not guarantee the order in which the Promises are resolved), I use Array.prototype.reduce, starting with a resolved Promise:



                    async function printFiles () {
                    const files = await getFilePaths();

                    await files.reduce(async (promise, file) => {
                    // This line will wait for the last async function to finish.
                    // The first iteration uses an already resolved Promise
                    // so, it will immediately continue.
                    await promise;
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    }, Promise.resolve());
                    }





                    share|improve this answer

















                    Instead of Promise.all in conjunction with Array.prototype.map (which does not guarantee the order in which the Promises are resolved), I use Array.prototype.reduce, starting with a resolved Promise:



                    async function printFiles () {
                    const files = await getFilePaths();

                    await files.reduce(async (promise, file) => {
                    // This line will wait for the last async function to finish.
                    // The first iteration uses an already resolved Promise
                    // so, it will immediately continue.
                    await promise;
                    const contents = await fs.readFile(file, 'utf8');
                    console.log(contents);
                    }, Promise.resolve());
                    }






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Mar 3 at 3:38

























                    answered Mar 26 '18 at 19:48









                    Timothy ZornTimothy Zorn

                    818715




                    818715








                    • 1





                      This works perfectly, thank you so much. Could you explain what is happening here with Promise.resolve() and await promise;?

                      – parrker9
                      Mar 28 '18 at 20:48






                    • 1





                      This is pretty cool. Am I right in thinking the files will be read in order and not all at once?

                      – GollyJer
                      Jun 9 '18 at 0:24






                    • 1





                      @parrker9 Promise.resolve() returns an already resolved Promise object, so that reduce has a Promise to start with. await promise; will wait for the last Promise in the chain to resolve. @GollyJer The files will be processed sequentially, one at a time.

                      – Timothy Zorn
                      Jun 17 '18 at 15:00
















                    • 1





                      This works perfectly, thank you so much. Could you explain what is happening here with Promise.resolve() and await promise;?

                      – parrker9
                      Mar 28 '18 at 20:48






                    • 1





                      This is pretty cool. Am I right in thinking the files will be read in order and not all at once?

                      – GollyJer
                      Jun 9 '18 at 0:24






                    • 1





                      @parrker9 Promise.resolve() returns an already resolved Promise object, so that reduce has a Promise to start with. await promise; will wait for the last Promise in the chain to resolve. @GollyJer The files will be processed sequentially, one at a time.

                      – Timothy Zorn
                      Jun 17 '18 at 15:00










                    1




                    1





                    This works perfectly, thank you so much. Could you explain what is happening here with Promise.resolve() and await promise;?

                    – parrker9
                    Mar 28 '18 at 20:48





                    This works perfectly, thank you so much. Could you explain what is happening here with Promise.resolve() and await promise;?

                    – parrker9
                    Mar 28 '18 at 20:48




                    1




                    1





                    This is pretty cool. Am I right in thinking the files will be read in order and not all at once?

                    – GollyJer
                    Jun 9 '18 at 0:24





                    This is pretty cool. Am I right in thinking the files will be read in order and not all at once?

                    – GollyJer
                    Jun 9 '18 at 0:24




                    1




                    1





                    @parrker9 Promise.resolve() returns an already resolved Promise object, so that reduce has a Promise to start with. await promise; will wait for the last Promise in the chain to resolve. @GollyJer The files will be processed sequentially, one at a time.

                    – Timothy Zorn
                    Jun 17 '18 at 15:00







                    @parrker9 Promise.resolve() returns an already resolved Promise object, so that reduce has a Promise to start with. await promise; will wait for the last Promise in the chain to resolve. @GollyJer The files will be processed sequentially, one at a time.

                    – Timothy Zorn
                    Jun 17 '18 at 15:00













                    11














                    Here are some forEach async prototypes:



                    Array.prototype.forEachAsync = async function (fn) {
                    for (let t of this) { await fn(t) }
                    }

                    Array.prototype.forEachAsyncParallel = async function (fn) {
                    await Promise.all(this.map(fn));
                    }





                    share|improve this answer



















                    • 1





                      Although I'd hesitate to add things directly to the prototype, this is a nice async forEach implementation

                      – DaniOcean
                      Mar 28 '18 at 13:55











                    • As long as the name is unique in the future (like I'd use _forEachAsync) this is reasonable. I also think it's the nicest answer as it saves a lot of boilerplate code.

                      – mikemaccana
                      Apr 3 '18 at 13:29











                    • They should be standalone functions. We've got modules to not pollute globals with our personal things.

                      – estus
                      Nov 5 '18 at 6:25
















                    11














                    Here are some forEach async prototypes:



                    Array.prototype.forEachAsync = async function (fn) {
                    for (let t of this) { await fn(t) }
                    }

                    Array.prototype.forEachAsyncParallel = async function (fn) {
                    await Promise.all(this.map(fn));
                    }





                    share|improve this answer



















                    • 1





                      Although I'd hesitate to add things directly to the prototype, this is a nice async forEach implementation

                      – DaniOcean
                      Mar 28 '18 at 13:55











                    • As long as the name is unique in the future (like I'd use _forEachAsync) this is reasonable. I also think it's the nicest answer as it saves a lot of boilerplate code.

                      – mikemaccana
                      Apr 3 '18 at 13:29











                    • They should be standalone functions. We've got modules to not pollute globals with our personal things.

                      – estus
                      Nov 5 '18 at 6:25














                    11












                    11








                    11







                    Here are some forEach async prototypes:



                    Array.prototype.forEachAsync = async function (fn) {
                    for (let t of this) { await fn(t) }
                    }

                    Array.prototype.forEachAsyncParallel = async function (fn) {
                    await Promise.all(this.map(fn));
                    }





                    share|improve this answer













                    Here are some forEach async prototypes:



                    Array.prototype.forEachAsync = async function (fn) {
                    for (let t of this) { await fn(t) }
                    }

                    Array.prototype.forEachAsyncParallel = async function (fn) {
                    await Promise.all(this.map(fn));
                    }






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Mar 22 '18 at 15:11









                    MattMatt

                    845313




                    845313








                    • 1





                      Although I'd hesitate to add things directly to the prototype, this is a nice async forEach implementation

                      – DaniOcean
                      Mar 28 '18 at 13:55











                    • As long as the name is unique in the future (like I'd use _forEachAsync) this is reasonable. I also think it's the nicest answer as it saves a lot of boilerplate code.

                      – mikemaccana
                      Apr 3 '18 at 13:29











                    • They should be standalone functions. We've got modules to not pollute globals with our personal things.

                      – estus
                      Nov 5 '18 at 6:25














                    • 1





                      Although I'd hesitate to add things directly to the prototype, this is a nice async forEach implementation

                      – DaniOcean
                      Mar 28 '18 at 13:55











                    • As long as the name is unique in the future (like I'd use _forEachAsync) this is reasonable. I also think it's the nicest answer as it saves a lot of boilerplate code.

                      – mikemaccana
                      Apr 3 '18 at 13:29











                    • They should be standalone functions. We've got modules to not pollute globals with our personal things.

                      – estus
                      Nov 5 '18 at 6:25








                    1




                    1





                    Although I'd hesitate to add things directly to the prototype, this is a nice async forEach implementation

                    – DaniOcean
                    Mar 28 '18 at 13:55





                    Although I'd hesitate to add things directly to the prototype, this is a nice async forEach implementation

                    – DaniOcean
                    Mar 28 '18 at 13:55













                    As long as the name is unique in the future (like I'd use _forEachAsync) this is reasonable. I also think it's the nicest answer as it saves a lot of boilerplate code.

                    – mikemaccana
                    Apr 3 '18 at 13:29





                    As long as the name is unique in the future (like I'd use _forEachAsync) this is reasonable. I also think it's the nicest answer as it saves a lot of boilerplate code.

                    – mikemaccana
                    Apr 3 '18 at 13:29













                    They should be standalone functions. We've got modules to not pollute globals with our personal things.

                    – estus
                    Nov 5 '18 at 6:25





                    They should be standalone functions. We've got modules to not pollute globals with our personal things.

                    – estus
                    Nov 5 '18 at 6:25











                    2














                    Both the solutions above work, however, Antonio's does the job with less code, here is how it helped me resolve data from my database, from several different child refs and then pushing them all into an array and resolving it in a promise after all is done:



                    Promise.all(PacksList.map((pack)=>{
                    return fireBaseRef.child(pack.folderPath).once('value',(snap)=>{
                    snap.forEach( childSnap => {
                    const file = childSnap.val()
                    file.id = childSnap.key;
                    allItems.push( file )
                    })
                    })
                    })).then(()=>store.dispatch( actions.allMockupItems(allItems)))





                    share|improve this answer




























                      2














                      Both the solutions above work, however, Antonio's does the job with less code, here is how it helped me resolve data from my database, from several different child refs and then pushing them all into an array and resolving it in a promise after all is done:



                      Promise.all(PacksList.map((pack)=>{
                      return fireBaseRef.child(pack.folderPath).once('value',(snap)=>{
                      snap.forEach( childSnap => {
                      const file = childSnap.val()
                      file.id = childSnap.key;
                      allItems.push( file )
                      })
                      })
                      })).then(()=>store.dispatch( actions.allMockupItems(allItems)))





                      share|improve this answer


























                        2












                        2








                        2







                        Both the solutions above work, however, Antonio's does the job with less code, here is how it helped me resolve data from my database, from several different child refs and then pushing them all into an array and resolving it in a promise after all is done:



                        Promise.all(PacksList.map((pack)=>{
                        return fireBaseRef.child(pack.folderPath).once('value',(snap)=>{
                        snap.forEach( childSnap => {
                        const file = childSnap.val()
                        file.id = childSnap.key;
                        allItems.push( file )
                        })
                        })
                        })).then(()=>store.dispatch( actions.allMockupItems(allItems)))





                        share|improve this answer













                        Both the solutions above work, however, Antonio's does the job with less code, here is how it helped me resolve data from my database, from several different child refs and then pushing them all into an array and resolving it in a promise after all is done:



                        Promise.all(PacksList.map((pack)=>{
                        return fireBaseRef.child(pack.folderPath).once('value',(snap)=>{
                        snap.forEach( childSnap => {
                        const file = childSnap.val()
                        file.id = childSnap.key;
                        allItems.push( file )
                        })
                        })
                        })).then(()=>store.dispatch( actions.allMockupItems(allItems)))






                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Aug 26 '17 at 10:47









                        Hooman AskariHooman Askari

                        646821




                        646821























                            2














                            it's pretty painless to pop a couple methods in a file that will handle asynchronous data in a serialized order and give a more conventional flavour to your code. For example:



                            module.exports = function () {
                            var self = this;

                            this.each = async (items, fn) => {
                            if (items && items.length) {
                            await Promise.all(
                            items.map(async (item) => {
                            await fn(item);
                            }));
                            }
                            };

                            this.reduce = async (items, fn, initialValue) => {
                            await self.each(
                            items, async (item) => {
                            initialValue = await fn(initialValue, item);
                            });
                            return initialValue;
                            };
                            };


                            now, assuming that's saved at './myAsync.js' you can do something similar to the below in an adjacent file:



                            ...
                            /* your server setup here */
                            ...
                            var MyAsync = require('./myAsync');
                            var Cat = require('./models/Cat');
                            var Doje = require('./models/Doje');
                            var example = async () => {
                            var myAsync = new MyAsync();
                            var doje = await Doje.findOne({ name: 'Doje', noises: }).save();
                            var cleanParams = ;

                            // FOR EACH EXAMPLE
                            await myAsync.each(['bork', 'concern', 'heck'],
                            async (elem) => {
                            if (elem !== 'heck') {
                            await doje.update({ $push: { 'noises': elem }});
                            }
                            });

                            var cat = await Cat.findOne({ name: 'Nyan' });

                            // REDUCE EXAMPLE
                            var friendsOfNyanCat = await myAsync.reduce(cat.friends,
                            async (catArray, friendId) => {
                            var friend = await Friend.findById(friendId);
                            if (friend.name !== 'Long cat') {
                            catArray.push(friend.name);
                            }
                            }, );
                            // Assuming Long Cat was a friend of Nyan Cat...
                            assert(friendsOfNyanCat.length === (cat.friends.length - 1));
                            }





                            share|improve this answer





















                            • 2





                              Minor addendum, don't forget to wrap your await/asyncs in try/catch blocks!!

                              – Jay Edwards
                              Sep 26 '17 at 9:08
















                            2














                            it's pretty painless to pop a couple methods in a file that will handle asynchronous data in a serialized order and give a more conventional flavour to your code. For example:



                            module.exports = function () {
                            var self = this;

                            this.each = async (items, fn) => {
                            if (items && items.length) {
                            await Promise.all(
                            items.map(async (item) => {
                            await fn(item);
                            }));
                            }
                            };

                            this.reduce = async (items, fn, initialValue) => {
                            await self.each(
                            items, async (item) => {
                            initialValue = await fn(initialValue, item);
                            });
                            return initialValue;
                            };
                            };


                            now, assuming that's saved at './myAsync.js' you can do something similar to the below in an adjacent file:



                            ...
                            /* your server setup here */
                            ...
                            var MyAsync = require('./myAsync');
                            var Cat = require('./models/Cat');
                            var Doje = require('./models/Doje');
                            var example = async () => {
                            var myAsync = new MyAsync();
                            var doje = await Doje.findOne({ name: 'Doje', noises: }).save();
                            var cleanParams = ;

                            // FOR EACH EXAMPLE
                            await myAsync.each(['bork', 'concern', 'heck'],
                            async (elem) => {
                            if (elem !== 'heck') {
                            await doje.update({ $push: { 'noises': elem }});
                            }
                            });

                            var cat = await Cat.findOne({ name: 'Nyan' });

                            // REDUCE EXAMPLE
                            var friendsOfNyanCat = await myAsync.reduce(cat.friends,
                            async (catArray, friendId) => {
                            var friend = await Friend.findById(friendId);
                            if (friend.name !== 'Long cat') {
                            catArray.push(friend.name);
                            }
                            }, );
                            // Assuming Long Cat was a friend of Nyan Cat...
                            assert(friendsOfNyanCat.length === (cat.friends.length - 1));
                            }





                            share|improve this answer





















                            • 2





                              Minor addendum, don't forget to wrap your await/asyncs in try/catch blocks!!

                              – Jay Edwards
                              Sep 26 '17 at 9:08














                            2












                            2








                            2







                            it's pretty painless to pop a couple methods in a file that will handle asynchronous data in a serialized order and give a more conventional flavour to your code. For example:



                            module.exports = function () {
                            var self = this;

                            this.each = async (items, fn) => {
                            if (items && items.length) {
                            await Promise.all(
                            items.map(async (item) => {
                            await fn(item);
                            }));
                            }
                            };

                            this.reduce = async (items, fn, initialValue) => {
                            await self.each(
                            items, async (item) => {
                            initialValue = await fn(initialValue, item);
                            });
                            return initialValue;
                            };
                            };


                            now, assuming that's saved at './myAsync.js' you can do something similar to the below in an adjacent file:



                            ...
                            /* your server setup here */
                            ...
                            var MyAsync = require('./myAsync');
                            var Cat = require('./models/Cat');
                            var Doje = require('./models/Doje');
                            var example = async () => {
                            var myAsync = new MyAsync();
                            var doje = await Doje.findOne({ name: 'Doje', noises: }).save();
                            var cleanParams = ;

                            // FOR EACH EXAMPLE
                            await myAsync.each(['bork', 'concern', 'heck'],
                            async (elem) => {
                            if (elem !== 'heck') {
                            await doje.update({ $push: { 'noises': elem }});
                            }
                            });

                            var cat = await Cat.findOne({ name: 'Nyan' });

                            // REDUCE EXAMPLE
                            var friendsOfNyanCat = await myAsync.reduce(cat.friends,
                            async (catArray, friendId) => {
                            var friend = await Friend.findById(friendId);
                            if (friend.name !== 'Long cat') {
                            catArray.push(friend.name);
                            }
                            }, );
                            // Assuming Long Cat was a friend of Nyan Cat...
                            assert(friendsOfNyanCat.length === (cat.friends.length - 1));
                            }





                            share|improve this answer















                            it's pretty painless to pop a couple methods in a file that will handle asynchronous data in a serialized order and give a more conventional flavour to your code. For example:



                            module.exports = function () {
                            var self = this;

                            this.each = async (items, fn) => {
                            if (items && items.length) {
                            await Promise.all(
                            items.map(async (item) => {
                            await fn(item);
                            }));
                            }
                            };

                            this.reduce = async (items, fn, initialValue) => {
                            await self.each(
                            items, async (item) => {
                            initialValue = await fn(initialValue, item);
                            });
                            return initialValue;
                            };
                            };


                            now, assuming that's saved at './myAsync.js' you can do something similar to the below in an adjacent file:



                            ...
                            /* your server setup here */
                            ...
                            var MyAsync = require('./myAsync');
                            var Cat = require('./models/Cat');
                            var Doje = require('./models/Doje');
                            var example = async () => {
                            var myAsync = new MyAsync();
                            var doje = await Doje.findOne({ name: 'Doje', noises: }).save();
                            var cleanParams = ;

                            // FOR EACH EXAMPLE
                            await myAsync.each(['bork', 'concern', 'heck'],
                            async (elem) => {
                            if (elem !== 'heck') {
                            await doje.update({ $push: { 'noises': elem }});
                            }
                            });

                            var cat = await Cat.findOne({ name: 'Nyan' });

                            // REDUCE EXAMPLE
                            var friendsOfNyanCat = await myAsync.reduce(cat.friends,
                            async (catArray, friendId) => {
                            var friend = await Friend.findById(friendId);
                            if (friend.name !== 'Long cat') {
                            catArray.push(friend.name);
                            }
                            }, );
                            // Assuming Long Cat was a friend of Nyan Cat...
                            assert(friendsOfNyanCat.length === (cat.friends.length - 1));
                            }






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Sep 26 '17 at 9:07

























                            answered Sep 22 '17 at 23:03









                            Jay EdwardsJay Edwards

                            192112




                            192112








                            • 2





                              Minor addendum, don't forget to wrap your await/asyncs in try/catch blocks!!

                              – Jay Edwards
                              Sep 26 '17 at 9:08














                            • 2





                              Minor addendum, don't forget to wrap your await/asyncs in try/catch blocks!!

                              – Jay Edwards
                              Sep 26 '17 at 9:08








                            2




                            2





                            Minor addendum, don't forget to wrap your await/asyncs in try/catch blocks!!

                            – Jay Edwards
                            Sep 26 '17 at 9:08





                            Minor addendum, don't forget to wrap your await/asyncs in try/catch blocks!!

                            – Jay Edwards
                            Sep 26 '17 at 9:08











                            1














                            Using Task, futurize, and a traversable List, you can simply do



                            async function printFiles() {
                            const files = await getFiles();

                            List(files).traverse( Task.of, f => readFile( f, 'utf-8'))
                            .fork( console.error, console.log)
                            }


                            Here is how you'd set this up



                            import fs from 'fs';
                            import { futurize } from 'futurize';
                            import Task from 'data.task';
                            import { List } from 'immutable-ext';

                            const future = futurizeP(Task)
                            const readFile = future(fs.readFile)


                            Another way to have structured the desired code would be



                            const printFiles = files => 
                            List(files).traverse( Task.of, fn => readFile( fn, 'utf-8'))
                            .fork( console.error, console.log)


                            Or perhaps even more functionally oriented



                            // 90% of encodings are utf-8, making that use case super easy is prudent

                            // handy-library.js
                            export const readFile = f =>
                            future(fs.readFile)( f, 'utf-8' )

                            export const arrayToTaskList = list => taskFn =>
                            List(files).traverse( Task.of, taskFn )

                            export const readFiles = files =>
                            arrayToTaskList( files, readFile )

                            export const printFiles = files =>
                            readFiles(files).fork( console.error, console.log)


                            Then from the parent function



                            async function main() {
                            /* awesome code with side-effects before */
                            printFiles( await getFiles() );
                            /* awesome code with side-effects after */
                            }


                            If you really wanted more flexibility in encoding, you could just do this (for fun, I'm using the proposed Pipe Forward operator )



                            import { curry, flip } from 'ramda'

                            export const readFile = fs.readFile
                            |> future,
                            |> curry,
                            |> flip

                            export const readFileUtf8 = readFile('utf-8')


                            PS - I didn't try this code on the console, might have some typos... "straight freestyle, off the top of the dome!" as the 90s kids would say. :-p






                            share|improve this answer






























                              1














                              Using Task, futurize, and a traversable List, you can simply do



                              async function printFiles() {
                              const files = await getFiles();

                              List(files).traverse( Task.of, f => readFile( f, 'utf-8'))
                              .fork( console.error, console.log)
                              }


                              Here is how you'd set this up



                              import fs from 'fs';
                              import { futurize } from 'futurize';
                              import Task from 'data.task';
                              import { List } from 'immutable-ext';

                              const future = futurizeP(Task)
                              const readFile = future(fs.readFile)


                              Another way to have structured the desired code would be



                              const printFiles = files => 
                              List(files).traverse( Task.of, fn => readFile( fn, 'utf-8'))
                              .fork( console.error, console.log)


                              Or perhaps even more functionally oriented



                              // 90% of encodings are utf-8, making that use case super easy is prudent

                              // handy-library.js
                              export const readFile = f =>
                              future(fs.readFile)( f, 'utf-8' )

                              export const arrayToTaskList = list => taskFn =>
                              List(files).traverse( Task.of, taskFn )

                              export const readFiles = files =>
                              arrayToTaskList( files, readFile )

                              export const printFiles = files =>
                              readFiles(files).fork( console.error, console.log)


                              Then from the parent function



                              async function main() {
                              /* awesome code with side-effects before */
                              printFiles( await getFiles() );
                              /* awesome code with side-effects after */
                              }


                              If you really wanted more flexibility in encoding, you could just do this (for fun, I'm using the proposed Pipe Forward operator )



                              import { curry, flip } from 'ramda'

                              export const readFile = fs.readFile
                              |> future,
                              |> curry,
                              |> flip

                              export const readFileUtf8 = readFile('utf-8')


                              PS - I didn't try this code on the console, might have some typos... "straight freestyle, off the top of the dome!" as the 90s kids would say. :-p






                              share|improve this answer




























                                1












                                1








                                1







                                Using Task, futurize, and a traversable List, you can simply do



                                async function printFiles() {
                                const files = await getFiles();

                                List(files).traverse( Task.of, f => readFile( f, 'utf-8'))
                                .fork( console.error, console.log)
                                }


                                Here is how you'd set this up



                                import fs from 'fs';
                                import { futurize } from 'futurize';
                                import Task from 'data.task';
                                import { List } from 'immutable-ext';

                                const future = futurizeP(Task)
                                const readFile = future(fs.readFile)


                                Another way to have structured the desired code would be



                                const printFiles = files => 
                                List(files).traverse( Task.of, fn => readFile( fn, 'utf-8'))
                                .fork( console.error, console.log)


                                Or perhaps even more functionally oriented



                                // 90% of encodings are utf-8, making that use case super easy is prudent

                                // handy-library.js
                                export const readFile = f =>
                                future(fs.readFile)( f, 'utf-8' )

                                export const arrayToTaskList = list => taskFn =>
                                List(files).traverse( Task.of, taskFn )

                                export const readFiles = files =>
                                arrayToTaskList( files, readFile )

                                export const printFiles = files =>
                                readFiles(files).fork( console.error, console.log)


                                Then from the parent function



                                async function main() {
                                /* awesome code with side-effects before */
                                printFiles( await getFiles() );
                                /* awesome code with side-effects after */
                                }


                                If you really wanted more flexibility in encoding, you could just do this (for fun, I'm using the proposed Pipe Forward operator )



                                import { curry, flip } from 'ramda'

                                export const readFile = fs.readFile
                                |> future,
                                |> curry,
                                |> flip

                                export const readFileUtf8 = readFile('utf-8')


                                PS - I didn't try this code on the console, might have some typos... "straight freestyle, off the top of the dome!" as the 90s kids would say. :-p






                                share|improve this answer















                                Using Task, futurize, and a traversable List, you can simply do



                                async function printFiles() {
                                const files = await getFiles();

                                List(files).traverse( Task.of, f => readFile( f, 'utf-8'))
                                .fork( console.error, console.log)
                                }


                                Here is how you'd set this up



                                import fs from 'fs';
                                import { futurize } from 'futurize';
                                import Task from 'data.task';
                                import { List } from 'immutable-ext';

                                const future = futurizeP(Task)
                                const readFile = future(fs.readFile)


                                Another way to have structured the desired code would be



                                const printFiles = files => 
                                List(files).traverse( Task.of, fn => readFile( fn, 'utf-8'))
                                .fork( console.error, console.log)


                                Or perhaps even more functionally oriented



                                // 90% of encodings are utf-8, making that use case super easy is prudent

                                // handy-library.js
                                export const readFile = f =>
                                future(fs.readFile)( f, 'utf-8' )

                                export const arrayToTaskList = list => taskFn =>
                                List(files).traverse( Task.of, taskFn )

                                export const readFiles = files =>
                                arrayToTaskList( files, readFile )

                                export const printFiles = files =>
                                readFiles(files).fork( console.error, console.log)


                                Then from the parent function



                                async function main() {
                                /* awesome code with side-effects before */
                                printFiles( await getFiles() );
                                /* awesome code with side-effects after */
                                }


                                If you really wanted more flexibility in encoding, you could just do this (for fun, I'm using the proposed Pipe Forward operator )



                                import { curry, flip } from 'ramda'

                                export const readFile = fs.readFile
                                |> future,
                                |> curry,
                                |> flip

                                export const readFileUtf8 = readFile('utf-8')


                                PS - I didn't try this code on the console, might have some typos... "straight freestyle, off the top of the dome!" as the 90s kids would say. :-p







                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited Apr 3 '18 at 22:51

























                                answered Feb 28 '18 at 4:41









                                BabaknessBabakness

                                8431819




                                8431819























                                    1














                                    In addition to @Bergi’s answer, I’d like to offer a third alternative. It's very similar to @Bergi’s 2nd example, but instead of awaiting each readFile individually, you create an array of promises, each which you await at the end.



                                    import fs from 'fs-promise';
                                    async function printFiles () {
                                    const files = await getFilePaths();

                                    const promises = files.map((file) => fs.readFile(file, 'utf8'))

                                    const contents = await Promise.all(promises)

                                    contents.forEach(console.log);
                                    }


                                    Note that the function passed to .map() does not need to be async, since fs.readFile returns a Promise object anyway. Therefore promises is an array of Promise objects, which can be sent to Promise.all().



                                    In @Bergi’s answer, the console may log file contents out of order. For example if a really small file finishes reading before a really large file, it will be logged first, even if the small file comes after the large file in the files array. However, in my method above, you are guaranteed the console will log the files in the same order as they are read.






                                    share|improve this answer






























                                      1














                                      In addition to @Bergi’s answer, I’d like to offer a third alternative. It's very similar to @Bergi’s 2nd example, but instead of awaiting each readFile individually, you create an array of promises, each which you await at the end.



                                      import fs from 'fs-promise';
                                      async function printFiles () {
                                      const files = await getFilePaths();

                                      const promises = files.map((file) => fs.readFile(file, 'utf8'))

                                      const contents = await Promise.all(promises)

                                      contents.forEach(console.log);
                                      }


                                      Note that the function passed to .map() does not need to be async, since fs.readFile returns a Promise object anyway. Therefore promises is an array of Promise objects, which can be sent to Promise.all().



                                      In @Bergi’s answer, the console may log file contents out of order. For example if a really small file finishes reading before a really large file, it will be logged first, even if the small file comes after the large file in the files array. However, in my method above, you are guaranteed the console will log the files in the same order as they are read.






                                      share|improve this answer




























                                        1












                                        1








                                        1







                                        In addition to @Bergi’s answer, I’d like to offer a third alternative. It's very similar to @Bergi’s 2nd example, but instead of awaiting each readFile individually, you create an array of promises, each which you await at the end.



                                        import fs from 'fs-promise';
                                        async function printFiles () {
                                        const files = await getFilePaths();

                                        const promises = files.map((file) => fs.readFile(file, 'utf8'))

                                        const contents = await Promise.all(promises)

                                        contents.forEach(console.log);
                                        }


                                        Note that the function passed to .map() does not need to be async, since fs.readFile returns a Promise object anyway. Therefore promises is an array of Promise objects, which can be sent to Promise.all().



                                        In @Bergi’s answer, the console may log file contents out of order. For example if a really small file finishes reading before a really large file, it will be logged first, even if the small file comes after the large file in the files array. However, in my method above, you are guaranteed the console will log the files in the same order as they are read.






                                        share|improve this answer















                                        In addition to @Bergi’s answer, I’d like to offer a third alternative. It's very similar to @Bergi’s 2nd example, but instead of awaiting each readFile individually, you create an array of promises, each which you await at the end.



                                        import fs from 'fs-promise';
                                        async function printFiles () {
                                        const files = await getFilePaths();

                                        const promises = files.map((file) => fs.readFile(file, 'utf8'))

                                        const contents = await Promise.all(promises)

                                        contents.forEach(console.log);
                                        }


                                        Note that the function passed to .map() does not need to be async, since fs.readFile returns a Promise object anyway. Therefore promises is an array of Promise objects, which can be sent to Promise.all().



                                        In @Bergi’s answer, the console may log file contents out of order. For example if a really small file finishes reading before a really large file, it will be logged first, even if the small file comes after the large file in the files array. However, in my method above, you are guaranteed the console will log the files in the same order as they are read.







                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited Apr 21 '18 at 21:21

























                                        answered Feb 23 '18 at 0:47









                                        chharveychharvey

                                        3,34133362




                                        3,34133362























                                            0














                                            One important caveat is: The await + for .. of method and the forEach + async way actually have different effect.



                                            Having await inside a real for loop will make sure all async calls are executed one by one. And the forEach + async way will fire off all promises at the same time, which is faster but sometimes overwhelmed(if you do some DB query or visit some web services with volume restrictions and do not want to fire 100,000 calls at a time).



                                            You can also use reduce + promise(less elegant) if you do not use async/await and want to make sure files are read one after another.



                                            files.reduce((lastPromise, file) => 
                                            lastPromise.then(() =>
                                            fs.readFile(file, 'utf8')
                                            ), Promise.resolve()
                                            )


                                            Or you can create a forEachAsync to help but basically use the same for loop underlying.



                                            Array.prototype.forEachAsync = async function(cb){
                                            for(let x of this){
                                            await cb(x);
                                            }
                                            }





                                            share|improve this answer
























                                            • Have a look at How to define method in javascript on Array.prototype and Object.prototype so that it doesn't appear in for in loop. Also you probably should use the same iteration as native forEach - accessing indices instead of relying on iterability - and pass the index to the callback.

                                              – Bergi
                                              Nov 16 '17 at 13:57











                                            • You can use Array.prototype.reduce in a way that uses an async function. I've shown an example in my answer: stackoverflow.com/a/49499491/2537258

                                              – Timothy Zorn
                                              Mar 26 '18 at 19:54
















                                            0














                                            One important caveat is: The await + for .. of method and the forEach + async way actually have different effect.



                                            Having await inside a real for loop will make sure all async calls are executed one by one. And the forEach + async way will fire off all promises at the same time, which is faster but sometimes overwhelmed(if you do some DB query or visit some web services with volume restrictions and do not want to fire 100,000 calls at a time).



                                            You can also use reduce + promise(less elegant) if you do not use async/await and want to make sure files are read one after another.



                                            files.reduce((lastPromise, file) => 
                                            lastPromise.then(() =>
                                            fs.readFile(file, 'utf8')
                                            ), Promise.resolve()
                                            )


                                            Or you can create a forEachAsync to help but basically use the same for loop underlying.



                                            Array.prototype.forEachAsync = async function(cb){
                                            for(let x of this){
                                            await cb(x);
                                            }
                                            }





                                            share|improve this answer
























                                            • Have a look at How to define method in javascript on Array.prototype and Object.prototype so that it doesn't appear in for in loop. Also you probably should use the same iteration as native forEach - accessing indices instead of relying on iterability - and pass the index to the callback.

                                              – Bergi
                                              Nov 16 '17 at 13:57











                                            • You can use Array.prototype.reduce in a way that uses an async function. I've shown an example in my answer: stackoverflow.com/a/49499491/2537258

                                              – Timothy Zorn
                                              Mar 26 '18 at 19:54














                                            0












                                            0








                                            0







                                            One important caveat is: The await + for .. of method and the forEach + async way actually have different effect.



                                            Having await inside a real for loop will make sure all async calls are executed one by one. And the forEach + async way will fire off all promises at the same time, which is faster but sometimes overwhelmed(if you do some DB query or visit some web services with volume restrictions and do not want to fire 100,000 calls at a time).



                                            You can also use reduce + promise(less elegant) if you do not use async/await and want to make sure files are read one after another.



                                            files.reduce((lastPromise, file) => 
                                            lastPromise.then(() =>
                                            fs.readFile(file, 'utf8')
                                            ), Promise.resolve()
                                            )


                                            Or you can create a forEachAsync to help but basically use the same for loop underlying.



                                            Array.prototype.forEachAsync = async function(cb){
                                            for(let x of this){
                                            await cb(x);
                                            }
                                            }





                                            share|improve this answer













                                            One important caveat is: The await + for .. of method and the forEach + async way actually have different effect.



                                            Having await inside a real for loop will make sure all async calls are executed one by one. And the forEach + async way will fire off all promises at the same time, which is faster but sometimes overwhelmed(if you do some DB query or visit some web services with volume restrictions and do not want to fire 100,000 calls at a time).



                                            You can also use reduce + promise(less elegant) if you do not use async/await and want to make sure files are read one after another.



                                            files.reduce((lastPromise, file) => 
                                            lastPromise.then(() =>
                                            fs.readFile(file, 'utf8')
                                            ), Promise.resolve()
                                            )


                                            Or you can create a forEachAsync to help but basically use the same for loop underlying.



                                            Array.prototype.forEachAsync = async function(cb){
                                            for(let x of this){
                                            await cb(x);
                                            }
                                            }






                                            share|improve this answer












                                            share|improve this answer



                                            share|improve this answer










                                            answered Sep 24 '17 at 20:00









                                            Leon liLeon li

                                            2,8942829




                                            2,8942829













                                            • Have a look at How to define method in javascript on Array.prototype and Object.prototype so that it doesn't appear in for in loop. Also you probably should use the same iteration as native forEach - accessing indices instead of relying on iterability - and pass the index to the callback.

                                              – Bergi
                                              Nov 16 '17 at 13:57











                                            • You can use Array.prototype.reduce in a way that uses an async function. I've shown an example in my answer: stackoverflow.com/a/49499491/2537258

                                              – Timothy Zorn
                                              Mar 26 '18 at 19:54



















                                            • Have a look at How to define method in javascript on Array.prototype and Object.prototype so that it doesn't appear in for in loop. Also you probably should use the same iteration as native forEach - accessing indices instead of relying on iterability - and pass the index to the callback.

                                              – Bergi
                                              Nov 16 '17 at 13:57











                                            • You can use Array.prototype.reduce in a way that uses an async function. I've shown an example in my answer: stackoverflow.com/a/49499491/2537258

                                              – Timothy Zorn
                                              Mar 26 '18 at 19:54

















                                            Have a look at How to define method in javascript on Array.prototype and Object.prototype so that it doesn't appear in for in loop. Also you probably should use the same iteration as native forEach - accessing indices instead of relying on iterability - and pass the index to the callback.

                                            – Bergi
                                            Nov 16 '17 at 13:57





                                            Have a look at How to define method in javascript on Array.prototype and Object.prototype so that it doesn't appear in for in loop. Also you probably should use the same iteration as native forEach - accessing indices instead of relying on iterability - and pass the index to the callback.

                                            – Bergi
                                            Nov 16 '17 at 13:57













                                            You can use Array.prototype.reduce in a way that uses an async function. I've shown an example in my answer: stackoverflow.com/a/49499491/2537258

                                            – Timothy Zorn
                                            Mar 26 '18 at 19:54





                                            You can use Array.prototype.reduce in a way that uses an async function. I've shown an example in my answer: stackoverflow.com/a/49499491/2537258

                                            – Timothy Zorn
                                            Mar 26 '18 at 19:54











                                            0














                                            Similar to Antonio Val's p-iteration, an alternative npm module is async-af:



                                            const AsyncAF = require('async-af');
                                            const fs = require('fs-promise');

                                            function printFiles() {
                                            // since AsyncAF accepts promises or non-promises, there's no need to await here
                                            const files = getFilePaths();

                                            AsyncAF(files).forEach(async file => {
                                            const contents = await fs.readFile(file, 'utf8');
                                            console.log(contents);
                                            });
                                            }

                                            printFiles();


                                            Alternatively, async-af has a static method (log/logAF) that logs the results of promises:



                                            const AsyncAF = require('async-af');
                                            const fs = require('fs-promise');

                                            function printFiles() {
                                            const files = getFilePaths();

                                            AsyncAF(files).forEach(file => {
                                            AsyncAF.log(fs.readFile(file, 'utf8'));
                                            });
                                            }

                                            printFiles();


                                            However, the main advantage of the library is that you can chain asynchronous methods to do something like:



                                            const aaf = require('async-af');
                                            const fs = require('fs-promise');

                                            const printFiles = () => aaf(getFilePaths())
                                            .map(file => fs.readFile(file, 'utf8'))
                                            .forEach(file => aaf.log(file));

                                            printFiles();


                                            async-af






                                            share|improve this answer




























                                              0














                                              Similar to Antonio Val's p-iteration, an alternative npm module is async-af:



                                              const AsyncAF = require('async-af');
                                              const fs = require('fs-promise');

                                              function printFiles() {
                                              // since AsyncAF accepts promises or non-promises, there's no need to await here
                                              const files = getFilePaths();

                                              AsyncAF(files).forEach(async file => {
                                              const contents = await fs.readFile(file, 'utf8');
                                              console.log(contents);
                                              });
                                              }

                                              printFiles();


                                              Alternatively, async-af has a static method (log/logAF) that logs the results of promises:



                                              const AsyncAF = require('async-af');
                                              const fs = require('fs-promise');

                                              function printFiles() {
                                              const files = getFilePaths();

                                              AsyncAF(files).forEach(file => {
                                              AsyncAF.log(fs.readFile(file, 'utf8'));
                                              });
                                              }

                                              printFiles();


                                              However, the main advantage of the library is that you can chain asynchronous methods to do something like:



                                              const aaf = require('async-af');
                                              const fs = require('fs-promise');

                                              const printFiles = () => aaf(getFilePaths())
                                              .map(file => fs.readFile(file, 'utf8'))
                                              .forEach(file => aaf.log(file));

                                              printFiles();


                                              async-af






                                              share|improve this answer


























                                                0












                                                0








                                                0







                                                Similar to Antonio Val's p-iteration, an alternative npm module is async-af:



                                                const AsyncAF = require('async-af');
                                                const fs = require('fs-promise');

                                                function printFiles() {
                                                // since AsyncAF accepts promises or non-promises, there's no need to await here
                                                const files = getFilePaths();

                                                AsyncAF(files).forEach(async file => {
                                                const contents = await fs.readFile(file, 'utf8');
                                                console.log(contents);
                                                });
                                                }

                                                printFiles();


                                                Alternatively, async-af has a static method (log/logAF) that logs the results of promises:



                                                const AsyncAF = require('async-af');
                                                const fs = require('fs-promise');

                                                function printFiles() {
                                                const files = getFilePaths();

                                                AsyncAF(files).forEach(file => {
                                                AsyncAF.log(fs.readFile(file, 'utf8'));
                                                });
                                                }

                                                printFiles();


                                                However, the main advantage of the library is that you can chain asynchronous methods to do something like:



                                                const aaf = require('async-af');
                                                const fs = require('fs-promise');

                                                const printFiles = () => aaf(getFilePaths())
                                                .map(file => fs.readFile(file, 'utf8'))
                                                .forEach(file => aaf.log(file));

                                                printFiles();


                                                async-af






                                                share|improve this answer













                                                Similar to Antonio Val's p-iteration, an alternative npm module is async-af:



                                                const AsyncAF = require('async-af');
                                                const fs = require('fs-promise');

                                                function printFiles() {
                                                // since AsyncAF accepts promises or non-promises, there's no need to await here
                                                const files = getFilePaths();

                                                AsyncAF(files).forEach(async file => {
                                                const contents = await fs.readFile(file, 'utf8');
                                                console.log(contents);
                                                });
                                                }

                                                printFiles();


                                                Alternatively, async-af has a static method (log/logAF) that logs the results of promises:



                                                const AsyncAF = require('async-af');
                                                const fs = require('fs-promise');

                                                function printFiles() {
                                                const files = getFilePaths();

                                                AsyncAF(files).forEach(file => {
                                                AsyncAF.log(fs.readFile(file, 'utf8'));
                                                });
                                                }

                                                printFiles();


                                                However, the main advantage of the library is that you can chain asynchronous methods to do something like:



                                                const aaf = require('async-af');
                                                const fs = require('fs-promise');

                                                const printFiles = () => aaf(getFilePaths())
                                                .map(file => fs.readFile(file, 'utf8'))
                                                .forEach(file => aaf.log(file));

                                                printFiles();


                                                async-af







                                                share|improve this answer












                                                share|improve this answer



                                                share|improve this answer










                                                answered Jun 21 '18 at 16:55









                                                Scott RudigerScott Rudiger

                                                780313




                                                780313























                                                    0














                                                    Currently the Array.forEach prototype property doesn't support async operations, but we can create our own poly-fill to meet our needs.



                                                    // Example of asyncForEach Array poly-fill for NodeJs
                                                    // file: asyncForEach.js
                                                    // Define asynForEach function
                                                    async function asyncForEach(callback){
                                                    let indexer = 0
                                                    for(let data of this){
                                                    await callback(data, indexer)
                                                    indexer++
                                                    }
                                                    }
                                                    // Append it as an Array prototype property
                                                    Array.prototype.asyncForEach = asyncForEach
                                                    module.exports = {Array}


                                                    And that's it! You now have an async forEach method available on any arrays that are defined after these to operations.



                                                    Let's test it...



                                                    // Nodejs style
                                                    // file: someOtherFile.js

                                                    const readline = require('readline')
                                                    Array = require('./asyncForEach').Array
                                                    const log = console.log

                                                    // Create a stream interface
                                                    function createReader(options={prompt: '>'}){
                                                    return readline.createInterface({
                                                    input: process.stdin
                                                    ,output: process.stdout
                                                    ,prompt: options.prompt !== undefined ? options.prompt : '>'
                                                    })
                                                    }
                                                    // Create a cli stream reader
                                                    async function getUserIn(question, options={prompt:'>'}){
                                                    log(question)
                                                    let reader = createReader(options)
                                                    return new Promise((res)=>{
                                                    reader.on('line', (answer)=>{
                                                    process.stdout.cursorTo(0, 0)
                                                    process.stdout.clearScreenDown()
                                                    reader.close()
                                                    res(answer)
                                                    })
                                                    })
                                                    }

                                                    let questions = [
                                                    `What's your name`
                                                    ,`What's your favorite programming language`
                                                    ,`What's your favorite async function`
                                                    ]
                                                    let responses = {}

                                                    async function getResponses(){
                                                    // Notice we have to prepend await before calling the async Array function
                                                    // in order for it to function as expected
                                                    await questions.asyncForEach(async function(question, index){
                                                    let answer = await getUserIn(question)
                                                    responses[question] = answer
                                                    })
                                                    }

                                                    async function main(){
                                                    await getResponses()
                                                    log(responses)
                                                    }
                                                    main()
                                                    // Should prompt user for an answer to each question and then
                                                    // log each question and answer as an object to the terminal


                                                    We could do the same for some of the other array functions like map...



                                                    async function asyncMap(callback){
                                                    let newMap =
                                                    let indexer = 0
                                                    for(let data of this){
                                                    newMap[indexer] = await callback(data, indexer, this)
                                                    indexer++
                                                    }
                                                    return newMap
                                                    }

                                                    Array.prototype.asyncMap = asyncMap


                                                    ... and so on :)



                                                    Some things to note:




                                                    • Your callback must be an async function or promise

                                                    • Any arrays created before Array.prototype.<yourAsyncFunc> = <yourAsyncFunc> will not have this feature available






                                                    share|improve this answer




























                                                      0














                                                      Currently the Array.forEach prototype property doesn't support async operations, but we can create our own poly-fill to meet our needs.



                                                      // Example of asyncForEach Array poly-fill for NodeJs
                                                      // file: asyncForEach.js
                                                      // Define asynForEach function
                                                      async function asyncForEach(callback){
                                                      let indexer = 0
                                                      for(let data of this){
                                                      await callback(data, indexer)
                                                      indexer++
                                                      }
                                                      }
                                                      // Append it as an Array prototype property
                                                      Array.prototype.asyncForEach = asyncForEach
                                                      module.exports = {Array}


                                                      And that's it! You now have an async forEach method available on any arrays that are defined after these to operations.



                                                      Let's test it...



                                                      // Nodejs style
                                                      // file: someOtherFile.js

                                                      const readline = require('readline')
                                                      Array = require('./asyncForEach').Array
                                                      const log = console.log

                                                      // Create a stream interface
                                                      function createReader(options={prompt: '>'}){
                                                      return readline.createInterface({
                                                      input: process.stdin
                                                      ,output: process.stdout
                                                      ,prompt: options.prompt !== undefined ? options.prompt : '>'
                                                      })
                                                      }
                                                      // Create a cli stream reader
                                                      async function getUserIn(question, options={prompt:'>'}){
                                                      log(question)
                                                      let reader = createReader(options)
                                                      return new Promise((res)=>{
                                                      reader.on('line', (answer)=>{
                                                      process.stdout.cursorTo(0, 0)
                                                      process.stdout.clearScreenDown()
                                                      reader.close()
                                                      res(answer)
                                                      })
                                                      })
                                                      }

                                                      let questions = [
                                                      `What's your name`
                                                      ,`What's your favorite programming language`
                                                      ,`What's your favorite async function`
                                                      ]
                                                      let responses = {}

                                                      async function getResponses(){
                                                      // Notice we have to prepend await before calling the async Array function
                                                      // in order for it to function as expected
                                                      await questions.asyncForEach(async function(question, index){
                                                      let answer = await getUserIn(question)
                                                      responses[question] = answer
                                                      })
                                                      }

                                                      async function main(){
                                                      await getResponses()
                                                      log(responses)
                                                      }
                                                      main()
                                                      // Should prompt user for an answer to each question and then
                                                      // log each question and answer as an object to the terminal


                                                      We could do the same for some of the other array functions like map...



                                                      async function asyncMap(callback){
                                                      let newMap =
                                                      let indexer = 0
                                                      for(let data of this){
                                                      newMap[indexer] = await callback(data, indexer, this)
                                                      indexer++
                                                      }
                                                      return newMap
                                                      }

                                                      Array.prototype.asyncMap = asyncMap


                                                      ... and so on :)



                                                      Some things to note:




                                                      • Your callback must be an async function or promise

                                                      • Any arrays created before Array.prototype.<yourAsyncFunc> = <yourAsyncFunc> will not have this feature available






                                                      share|improve this answer


























                                                        0












                                                        0








                                                        0







                                                        Currently the Array.forEach prototype property doesn't support async operations, but we can create our own poly-fill to meet our needs.



                                                        // Example of asyncForEach Array poly-fill for NodeJs
                                                        // file: asyncForEach.js
                                                        // Define asynForEach function
                                                        async function asyncForEach(callback){
                                                        let indexer = 0
                                                        for(let data of this){
                                                        await callback(data, indexer)
                                                        indexer++
                                                        }
                                                        }
                                                        // Append it as an Array prototype property
                                                        Array.prototype.asyncForEach = asyncForEach
                                                        module.exports = {Array}


                                                        And that's it! You now have an async forEach method available on any arrays that are defined after these to operations.



                                                        Let's test it...



                                                        // Nodejs style
                                                        // file: someOtherFile.js

                                                        const readline = require('readline')
                                                        Array = require('./asyncForEach').Array
                                                        const log = console.log

                                                        // Create a stream interface
                                                        function createReader(options={prompt: '>'}){
                                                        return readline.createInterface({
                                                        input: process.stdin
                                                        ,output: process.stdout
                                                        ,prompt: options.prompt !== undefined ? options.prompt : '>'
                                                        })
                                                        }
                                                        // Create a cli stream reader
                                                        async function getUserIn(question, options={prompt:'>'}){
                                                        log(question)
                                                        let reader = createReader(options)
                                                        return new Promise((res)=>{
                                                        reader.on('line', (answer)=>{
                                                        process.stdout.cursorTo(0, 0)
                                                        process.stdout.clearScreenDown()
                                                        reader.close()
                                                        res(answer)
                                                        })
                                                        })
                                                        }

                                                        let questions = [
                                                        `What's your name`
                                                        ,`What's your favorite programming language`
                                                        ,`What's your favorite async function`
                                                        ]
                                                        let responses = {}

                                                        async function getResponses(){
                                                        // Notice we have to prepend await before calling the async Array function
                                                        // in order for it to function as expected
                                                        await questions.asyncForEach(async function(question, index){
                                                        let answer = await getUserIn(question)
                                                        responses[question] = answer
                                                        })
                                                        }

                                                        async function main(){
                                                        await getResponses()
                                                        log(responses)
                                                        }
                                                        main()
                                                        // Should prompt user for an answer to each question and then
                                                        // log each question and answer as an object to the terminal


                                                        We could do the same for some of the other array functions like map...



                                                        async function asyncMap(callback){
                                                        let newMap =
                                                        let indexer = 0
                                                        for(let data of this){
                                                        newMap[indexer] = await callback(data, indexer, this)
                                                        indexer++
                                                        }
                                                        return newMap
                                                        }

                                                        Array.prototype.asyncMap = asyncMap


                                                        ... and so on :)



                                                        Some things to note:




                                                        • Your callback must be an async function or promise

                                                        • Any arrays created before Array.prototype.<yourAsyncFunc> = <yourAsyncFunc> will not have this feature available






                                                        share|improve this answer













                                                        Currently the Array.forEach prototype property doesn't support async operations, but we can create our own poly-fill to meet our needs.



                                                        // Example of asyncForEach Array poly-fill for NodeJs
                                                        // file: asyncForEach.js
                                                        // Define asynForEach function
                                                        async function asyncForEach(callback){
                                                        let indexer = 0
                                                        for(let data of this){
                                                        await callback(data, indexer)
                                                        indexer++
                                                        }
                                                        }
                                                        // Append it as an Array prototype property
                                                        Array.prototype.asyncForEach = asyncForEach
                                                        module.exports = {Array}


                                                        And that's it! You now have an async forEach method available on any arrays that are defined after these to operations.



                                                        Let's test it...



                                                        // Nodejs style
                                                        // file: someOtherFile.js

                                                        const readline = require('readline')
                                                        Array = require('./asyncForEach').Array
                                                        const log = console.log

                                                        // Create a stream interface
                                                        function createReader(options={prompt: '>'}){
                                                        return readline.createInterface({
                                                        input: process.stdin
                                                        ,output: process.stdout
                                                        ,prompt: options.prompt !== undefined ? options.prompt : '>'
                                                        })
                                                        }
                                                        // Create a cli stream reader
                                                        async function getUserIn(question, options={prompt:'>'}){
                                                        log(question)
                                                        let reader = createReader(options)
                                                        return new Promise((res)=>{
                                                        reader.on('line', (answer)=>{
                                                        process.stdout.cursorTo(0, 0)
                                                        process.stdout.clearScreenDown()
                                                        reader.close()
                                                        res(answer)
                                                        })
                                                        })
                                                        }

                                                        let questions = [
                                                        `What's your name`
                                                        ,`What's your favorite programming language`
                                                        ,`What's your favorite async function`
                                                        ]
                                                        let responses = {}

                                                        async function getResponses(){
                                                        // Notice we have to prepend await before calling the async Array function
                                                        // in order for it to function as expected
                                                        await questions.asyncForEach(async function(question, index){
                                                        let answer = await getUserIn(question)
                                                        responses[question] = answer
                                                        })
                                                        }

                                                        async function main(){
                                                        await getResponses()
                                                        log(responses)
                                                        }
                                                        main()
                                                        // Should prompt user for an answer to each question and then
                                                        // log each question and answer as an object to the terminal


                                                        We could do the same for some of the other array functions like map...



                                                        async function asyncMap(callback){
                                                        let newMap =
                                                        let indexer = 0
                                                        for(let data of this){
                                                        newMap[indexer] = await callback(data, indexer, this)
                                                        indexer++
                                                        }
                                                        return newMap
                                                        }

                                                        Array.prototype.asyncMap = asyncMap


                                                        ... and so on :)



                                                        Some things to note:




                                                        • Your callback must be an async function or promise

                                                        • Any arrays created before Array.prototype.<yourAsyncFunc> = <yourAsyncFunc> will not have this feature available







                                                        share|improve this answer












                                                        share|improve this answer



                                                        share|improve this answer










                                                        answered Mar 12 at 23:31









                                                        BeauBeau

                                                        213




                                                        213























                                                            -3














                                                            I would use the well-tested (millions of downloads per week) pify and async modules. If you are unfamiliar with the async module, I highly recommend you check out its docs. I've seen multiple devs waste time recreating its methods, or worse, making difficult-to-maintain async code when higher-order async methods would simplify code.






                                                            const async = require('async')
                                                            const fs = require('fs-promise')
                                                            const pify = require('pify')

                                                            async function getFilePaths() {
                                                            return Promise.resolve([
                                                            './package.json',
                                                            './package-lock.json',
                                                            ]);
                                                            }

                                                            async function printFiles () {
                                                            const files = await getFilePaths()

                                                            await pify(async.eachSeries)(files, async (file) => { // <-- run in series
                                                            // await pify(async.each)(files, async (file) => { // <-- run in parallel
                                                            const contents = await fs.readFile(file, 'utf8')
                                                            console.log(contents)
                                                            })
                                                            console.log('HAMBONE')
                                                            }

                                                            printFiles().then(() => {
                                                            console.log('HAMBUNNY')
                                                            })
                                                            // ORDER OF LOGS:
                                                            // package.json contents
                                                            // package-lock.json contents
                                                            // HAMBONE
                                                            // HAMBUNNY
                                                            ```








                                                            share|improve this answer
























                                                            • This is a step in the wrong direction. Here's a mapping guide I created to help get folks stuck in callback hell into the modern JS era: github.com/jmjpro/async-package-to-async-await/blob/master/….

                                                              – jbustamovej
                                                              Feb 20 '18 at 6:24











                                                            • as you can see here, I am interested in and open to using async/await instead of the async lib. Right now, I think that each has a time and place. I'm not convinced that the async lib == "callback hell" and async/await == "the modern JS era". imo, when async lib > async/await: 1. complex flow (eg, queue, cargo, even auto when things get complicated) 2. concurrency 3. supporting arrays/objects/iterables 4. err handling

                                                              – Zachary Ryan Smith
                                                              Feb 21 '18 at 1:54
















                                                            -3














                                                            I would use the well-tested (millions of downloads per week) pify and async modules. If you are unfamiliar with the async module, I highly recommend you check out its docs. I've seen multiple devs waste time recreating its methods, or worse, making difficult-to-maintain async code when higher-order async methods would simplify code.






                                                            const async = require('async')
                                                            const fs = require('fs-promise')
                                                            const pify = require('pify')

                                                            async function getFilePaths() {
                                                            return Promise.resolve([
                                                            './package.json',
                                                            './package-lock.json',
                                                            ]);
                                                            }

                                                            async function printFiles () {
                                                            const files = await getFilePaths()

                                                            await pify(async.eachSeries)(files, async (file) => { // <-- run in series
                                                            // await pify(async.each)(files, async (file) => { // <-- run in parallel
                                                            const contents = await fs.readFile(file, 'utf8')
                                                            console.log(contents)
                                                            })
                                                            console.log('HAMBONE')
                                                            }

                                                            printFiles().then(() => {
                                                            console.log('HAMBUNNY')
                                                            })
                                                            // ORDER OF LOGS:
                                                            // package.json contents
                                                            // package-lock.json contents
                                                            // HAMBONE
                                                            // HAMBUNNY
                                                            ```








                                                            share|improve this answer
























                                                            • This is a step in the wrong direction. Here's a mapping guide I created to help get folks stuck in callback hell into the modern JS era: github.com/jmjpro/async-package-to-async-await/blob/master/….

                                                              – jbustamovej
                                                              Feb 20 '18 at 6:24











                                                            • as you can see here, I am interested in and open to using async/await instead of the async lib. Right now, I think that each has a time and place. I'm not convinced that the async lib == "callback hell" and async/await == "the modern JS era". imo, when async lib > async/await: 1. complex flow (eg, queue, cargo, even auto when things get complicated) 2. concurrency 3. supporting arrays/objects/iterables 4. err handling

                                                              – Zachary Ryan Smith
                                                              Feb 21 '18 at 1:54














                                                            -3












                                                            -3








                                                            -3







                                                            I would use the well-tested (millions of downloads per week) pify and async modules. If you are unfamiliar with the async module, I highly recommend you check out its docs. I've seen multiple devs waste time recreating its methods, or worse, making difficult-to-maintain async code when higher-order async methods would simplify code.






                                                            const async = require('async')
                                                            const fs = require('fs-promise')
                                                            const pify = require('pify')

                                                            async function getFilePaths() {
                                                            return Promise.resolve([
                                                            './package.json',
                                                            './package-lock.json',
                                                            ]);
                                                            }

                                                            async function printFiles () {
                                                            const files = await getFilePaths()

                                                            await pify(async.eachSeries)(files, async (file) => { // <-- run in series
                                                            // await pify(async.each)(files, async (file) => { // <-- run in parallel
                                                            const contents = await fs.readFile(file, 'utf8')
                                                            console.log(contents)
                                                            })
                                                            console.log('HAMBONE')
                                                            }

                                                            printFiles().then(() => {
                                                            console.log('HAMBUNNY')
                                                            })
                                                            // ORDER OF LOGS:
                                                            // package.json contents
                                                            // package-lock.json contents
                                                            // HAMBONE
                                                            // HAMBUNNY
                                                            ```








                                                            share|improve this answer













                                                            I would use the well-tested (millions of downloads per week) pify and async modules. If you are unfamiliar with the async module, I highly recommend you check out its docs. I've seen multiple devs waste time recreating its methods, or worse, making difficult-to-maintain async code when higher-order async methods would simplify code.






                                                            const async = require('async')
                                                            const fs = require('fs-promise')
                                                            const pify = require('pify')

                                                            async function getFilePaths() {
                                                            return Promise.resolve([
                                                            './package.json',
                                                            './package-lock.json',
                                                            ]);
                                                            }

                                                            async function printFiles () {
                                                            const files = await getFilePaths()

                                                            await pify(async.eachSeries)(files, async (file) => { // <-- run in series
                                                            // await pify(async.each)(files, async (file) => { // <-- run in parallel
                                                            const contents = await fs.readFile(file, 'utf8')
                                                            console.log(contents)
                                                            })
                                                            console.log('HAMBONE')
                                                            }

                                                            printFiles().then(() => {
                                                            console.log('HAMBUNNY')
                                                            })
                                                            // ORDER OF LOGS:
                                                            // package.json contents
                                                            // package-lock.json contents
                                                            // HAMBONE
                                                            // HAMBUNNY
                                                            ```








                                                            const async = require('async')
                                                            const fs = require('fs-promise')
                                                            const pify = require('pify')

                                                            async function getFilePaths() {
                                                            return Promise.resolve([
                                                            './package.json',
                                                            './package-lock.json',
                                                            ]);
                                                            }

                                                            async function printFiles () {
                                                            const files = await getFilePaths()

                                                            await pify(async.eachSeries)(files, async (file) => { // <-- run in series
                                                            // await pify(async.each)(files, async (file) => { // <-- run in parallel
                                                            const contents = await fs.readFile(file, 'utf8')
                                                            console.log(contents)
                                                            })
                                                            console.log('HAMBONE')
                                                            }

                                                            printFiles().then(() => {
                                                            console.log('HAMBUNNY')
                                                            })
                                                            // ORDER OF LOGS:
                                                            // package.json contents
                                                            // package-lock.json contents
                                                            // HAMBONE
                                                            // HAMBUNNY
                                                            ```





                                                            const async = require('async')
                                                            const fs = require('fs-promise')
                                                            const pify = require('pify')

                                                            async function getFilePaths() {
                                                            return Promise.resolve([
                                                            './package.json',
                                                            './package-lock.json',
                                                            ]);
                                                            }

                                                            async function printFiles () {
                                                            const files = await getFilePaths()

                                                            await pify(async.eachSeries)(files, async (file) => { // <-- run in series
                                                            // await pify(async.each)(files, async (file) => { // <-- run in parallel
                                                            const contents = await fs.readFile(file, 'utf8')
                                                            console.log(contents)
                                                            })
                                                            console.log('HAMBONE')
                                                            }

                                                            printFiles().then(() => {
                                                            console.log('HAMBUNNY')
                                                            })
                                                            // ORDER OF LOGS:
                                                            // package.json contents
                                                            // package-lock.json contents
                                                            // HAMBONE
                                                            // HAMBUNNY
                                                            ```






                                                            share|improve this answer












                                                            share|improve this answer



                                                            share|improve this answer










                                                            answered Feb 4 '18 at 16:03









                                                            Zachary Ryan SmithZachary Ryan Smith

                                                            1,14911120




                                                            1,14911120













                                                            • This is a step in the wrong direction. Here's a mapping guide I created to help get folks stuck in callback hell into the modern JS era: github.com/jmjpro/async-package-to-async-await/blob/master/….

                                                              – jbustamovej
                                                              Feb 20 '18 at 6:24











                                                            • as you can see here, I am interested in and open to using async/await instead of the async lib. Right now, I think that each has a time and place. I'm not convinced that the async lib == "callback hell" and async/await == "the modern JS era". imo, when async lib > async/await: 1. complex flow (eg, queue, cargo, even auto when things get complicated) 2. concurrency 3. supporting arrays/objects/iterables 4. err handling

                                                              – Zachary Ryan Smith
                                                              Feb 21 '18 at 1:54



















                                                            • This is a step in the wrong direction. Here's a mapping guide I created to help get folks stuck in callback hell into the modern JS era: github.com/jmjpro/async-package-to-async-await/blob/master/….

                                                              – jbustamovej
                                                              Feb 20 '18 at 6:24











                                                            • as you can see here, I am interested in and open to using async/await instead of the async lib. Right now, I think that each has a time and place. I'm not convinced that the async lib == "callback hell" and async/await == "the modern JS era". imo, when async lib > async/await: 1. complex flow (eg, queue, cargo, even auto when things get complicated) 2. concurrency 3. supporting arrays/objects/iterables 4. err handling

                                                              – Zachary Ryan Smith
                                                              Feb 21 '18 at 1:54

















                                                            This is a step in the wrong direction. Here's a mapping guide I created to help get folks stuck in callback hell into the modern JS era: github.com/jmjpro/async-package-to-async-await/blob/master/….

                                                            – jbustamovej
                                                            Feb 20 '18 at 6:24





                                                            This is a step in the wrong direction. Here's a mapping guide I created to help get folks stuck in callback hell into the modern JS era: github.com/jmjpro/async-package-to-async-await/blob/master/….

                                                            – jbustamovej
                                                            Feb 20 '18 at 6:24













                                                            as you can see here, I am interested in and open to using async/await instead of the async lib. Right now, I think that each has a time and place. I'm not convinced that the async lib == "callback hell" and async/await == "the modern JS era". imo, when async lib > async/await: 1. complex flow (eg, queue, cargo, even auto when things get complicated) 2. concurrency 3. supporting arrays/objects/iterables 4. err handling

                                                            – Zachary Ryan Smith
                                                            Feb 21 '18 at 1:54





                                                            as you can see here, I am interested in and open to using async/await instead of the async lib. Right now, I think that each has a time and place. I'm not convinced that the async lib == "callback hell" and async/await == "the modern JS era". imo, when async lib > async/await: 1. complex flow (eg, queue, cargo, even auto when things get complicated) 2. concurrency 3. supporting arrays/objects/iterables 4. err handling

                                                            – Zachary Ryan Smith
                                                            Feb 21 '18 at 1:54





                                                            protected by georgeawg Aug 16 '18 at 17:41



                                                            Thank you for your interest in this question.
                                                            Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                                            Would you like to answer one of these unanswered questions instead?



                                                            Popular posts from this blog

                                                            Xamarin.iOS Cant Deploy on Iphone

                                                            Glorious Revolution

                                                            Dulmage-Mendelsohn matrix decomposition in Python