John Moran
John Moran

Reputation: 43

JS Async Directory Listing

I am attempting to loop through an array containing directories and then return a combined array of all the items regardless of the number of directories. I was attempting to use the fs.readdir function to read the directories, but seeing as the fs.readdir function is an async function I can't pass the information back out of it.

Is there a way to use this function, but also make an array of the directory listings?

This is what I would like to do, but I know that this is just wrong. Hoping for a little guidance. I can provide any additional info. Thank you.

var docs = [];
libs.forEach(function(lib){
    fs.readdir(lib, function(err, files){
        files.forEach(function(file){
            docs.push(file);
        });
    });
});

Upvotes: 0

Views: 398

Answers (1)

Sven
Sven

Reputation: 5265

An async version:

const fs = require("fs/promises");

function listDirectories(dirs) {
  return Promise.all(dirs.map(dir => fs.readdir(dir))).then(files => files.flat());
}

It maps an array of strings (directories) into an array of promises returned by fs.readdir, followed by flattening the results of those promises once they resolve using Array.prototype.flat. Flattening is required to transform this:

[ [ "file1" ], [ "file2", "file3" ] ] into [ "file1", "file2", "file3" ].

Then, from an async function you can call it like so:

(async () => {
  const dirs = ["one", "two", "three"];
  try {
    let files = await listDirectories(dirs);
    console.log(files);
  } catch (e) {
    console.error(e);
  }
})();

Note that the above is an IIFE (Immediately Invoked Function Expression) that you can use to test the function without having to integrate it into your codebase first.

Upvotes: 1

Related Questions