如何将递归回调函数转换为异步等待格式

时间:2018-07-23 10:11:17

标签: javascript node.js async-await

我想将递归回调函数转换为async-await格式,下面是代码,

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);
            }
        });
    });
}

这就是我所谓的函​​数,

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

以下是我所取得的进步,我不知道这是否是正确的方法,请指导我。

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);
            }
        });
    });
};

这就是我调用文件的方式

 let files = await findFiles('./logs');

2 个答案:

答案 0 :(得分:1)

首先,您需要传播fs函数或如果准备使用实验性API,则使用fsPromises-*函数。

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

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

那么你可以做这样的事情。

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)
    }
  }
}

答案 1 :(得分:1)

非常容易理解

这就是我调用函数的方式

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);
            }
        });
    });
};

此解决方案对我来说效果很好。