2

I want to convert recursive callback function to async-await format, the following is the code,

function findFiles(currentDirPath, callback) {
    fs.readdir(currentDirPath, function (err, files) {
        if (err) {
            throw new Error(err);
        }
        files.forEach(function (name) {
            var filePath = path.join(currentDirPath, name);
            var stat = fs.statSync(filePath);
            if (stat.isFile()) {
                callback(filePath, stat);
            } else if (stat.isDirectory()) { //if directory call function
                findFiles(filePath, callback);
            }
        });
    });
}

and this is how i call function,

findFiles('./logs', function(route){
    console.log(route);
});

following is the progress I've made, I don't know is it the right way or not, please guide me.

var bundle = [];
var findFiles = async function (root) {

    let files = await readFile(root);
    for(let inx in files){
        var filePath = path.join(root, files[inx]);
        var stat = fs.statSync(filePath);

        if (stat.isFile()) {
            bundle.push(filePath);
        } else if (stat.isDirectory()) {
            await findFiles(filePath);
        }

    }
    return bundle;
};

let readFile = function(dir){
    return new Promise((resolve, reject) => {
        fs.readdir(dir, function(err,files){
            if (!err) {
                resolve(files); 
            } else {
                reject(err);
            }
        });
    });
};

this is how i calling file,

 let files = await findFiles('./logs');
9
  • And the question is... Commented Jul 23, 2018 at 10:17
  • sorry, @YuryTarabanko I've corrected the question. Commented Jul 23, 2018 at 10:19
  • Well, have you tried anything? Also keep in mind that async/await only works with promises. Commented Jul 23, 2018 at 10:20
  • What did you try and what was the problem? Obviously, you need to use promises. Use for..of instead of forEach, it's obsolete. Commented Jul 23, 2018 at 10:20
  • @estus "forEach, it's obsolete" since when? Commented Jul 23, 2018 at 10:22

2 Answers 2

1

First you need to promisify fs functions or use fsPromises-* functions if you are ready to use experimental API..

const { promisify } = require('util')
const fs = require('fs')

const readdir = promisify(fs.readdir)
const stat = promisify(fs.stat) // to use instead of statSync

Then you could do something like this.

async function forEachFile(dir, fn) {
  const files = await readdir(dir)

  for( const item of files) {
    const filePath = path.join(dir, item)
    const stats = await stat(filePath);

    if (stats.isFile()) {
       await fn(filePath, stats) // in case fn is async
    } else if(stats.isDirectory()) {
       await forEachFile(filePath, fn)
    }
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Node 10 users don't need promisification step, there's fs.promises.
1

very easy to understand,

this is how I call function,

await (async ()=> {
   return new Promise(async function(resolve, reject) {
       await findFiles(configs.server.routes.root, function(route){
           console.log(route)
           //do things
        });
    });
})();

var findFiles = async function (root, callback) {

    let files = await readFile(root);
    for(let inx in files){
        var filePath = path.join(root, files[inx]);
        var stat = fs.statSync(filePath);

        if (stat.isFile()) {
            callback(filePath);
        } else if (stat.isDirectory()) {
            await findFiles(filePath, callback);
        }

    }
};

let readFile = function(dir){
    return new Promise((resolve, reject) => {
        fs.readdir(dir, function(err,files){
            if (!err) {
                resolve(files); 
            } else {
                reject(err);
            }
        });
    });
};

this solution is working perfectly fine for me.

1 Comment

@YuryTarabanko what is your opinion regarding this solution?

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.