Await an iterative function without delimiter in JS

后端 未结 2 1022
失恋的感觉
失恋的感觉 2020-12-03 20:49

I\'ve got a directory with an unknown amount of subfolders. Each subfolder might have or not further subfolders. I am itterating through them using a recursive function. Due

2条回答
  •  自闭症患者
    2020-12-03 21:15

    You have a few options:

    1) Since everything else is done using fs's synchronous methods, you could change fs.readdir to fs.readdirSync:

    function searchForPackage(directory) {
      fs.readdirSync(directory).forEach(file => {
        var currentLocation = directory + "/" + file;
        if (fs.statSync(currentLocation).isDirectory() && file != 'bin' && file != '.bin') {
          searchForPackage(currentLocation);
          return;
        } else if (file == "package.json") {
          var content = fs.readFileSync(currentLocation);
          var jsonContent = JSON.parse(content);
          var obj = {
            name: jsonContent.name,
            license: jsonContent.license,
            version: jsonContent.version
          }
          jsonTable.push(obj);
          jsonTable.push({name: jsonContent.name, license: jsonContent.license, version: jsonContent.version});
          return;
        }
      })
    }
    

    2) Convert fs.readdirSync to a Promise and then use async/await:

    async function searchForPackage(directory) {
      const files = await new Promise((resolve, reject) => {
        fs.readdir(directory, (err, files) => {
          if (err) reject(err);
          else resolve(files);
        });
      });
      await Promise.all(files.map(async file => {
        var currentLocation = directory + "/" + file;
        if (fs.statSync(currentLocation).isDirectory() && file != 'bin' && file != '.bin') {
          await searchForPackage(currentLocation);
          return;
        } else if (file == "package.json") {
          var content = fs.readFileSync(currentLocation);
          var jsonContent = JSON.parse(content);
          var obj = {
            name: jsonContent.name,
            license: jsonContent.license,
            version: jsonContent.version
          }
          jsonTable.push(obj);
          jsonTable.push({name: jsonContent.name, license: jsonContent.license, version: jsonContent.version});
          return;
        }
      }))
    }
    

    3) Use a couple third-party modules to clean things up a bit (fs-extra takes care of promisifying asynchronous methods like fs.readdir for you. async-af provides chainable asynchronous JavaScript methods such as a parallel forEach.):

    const fs = require('fs-extra');
    const AsyncAF = require('async-af');
    
    async function searchForPackage(directory) {
      await AsyncAF(fs.readdir(directory)).forEach(async file => {
        var currentLocation = directory + "/" + file;
        if (fs.statSync(currentLocation).isDirectory() && file != 'bin' && file != '.bin') {
          await searchForPackage(currentLocation);
        } else if (file == "package.json") {
          var content = fs.readFileSync(currentLocation);
          var jsonContent = JSON.parse(content);
          var obj = {
            name: jsonContent.name,
            license: jsonContent.license,
            version: jsonContent.version
          }
          jsonTable.push(obj);
          jsonTable.push({name: jsonContent.name, license: jsonContent.license, version: jsonContent.version});
        }
      });
    }
    

提交回复
热议问题