Node js异步等待函数不会相互等待

菜鸟

我有一个项目,它具有读取文件并提取其哈希码的功能。在项目中提取这些哈希码后,将一一构建子文件。最后,我想做的是将所有这些哈希码放入一个数组中并创建一个 json 文件。我需要在 IterateFolders() 函数在 readDirectory 函数中运行并完成之后执行此操作。但是console.log是在底线运行,没有等待这个功能,请帮忙。

我的功能如下:


//Calculate build time 
function getBuildTime(start,end) {
    let time = (end - start);
    let buildTime = `${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()} Build time: ${time} ms \n`   
    
    fs.writeFile('build-time.log', buildTime,function (err) { //output log file
        if (err) return console.log(err);
      });
}

//async metaHash calculation from folder path
async function computeMetaHash(folder, inputHash = null) {
    const hash = inputHash ? inputHash : createHash('sha256');
    const info = await fsp.readdir(folder, { withFileTypes: true });
    //construct a string from the modification date, the filename and the filesize
    for (let item of info) {
        const fullPath = path.join(folder, item.name)
        if (item.isFile()) {
            const statInfo = await fsp.stat(fullPath); //stat return all informations about file
            // compute hash string name:size:mtime
            const fileInfo = `${fullPath}:${statInfo.size}:${statInfo.mtimeMs}`;
            hash.update(fileInfo);        
        } else if (item.isDirectory()) {
            // recursively walk sub-folders
            await computeMetaHash(fullPath, hash);
        }
    }
    // if not being called recursively, get the digest and return it as the hash result
    if (!inputHash) {
        return hash.digest('base64');
    }
}


async function iterateFolders(folderPath) {
    folderPath.forEach(function (files) {
        //function takes folder path as inputh
        computeMetaHash(files).then(result => { //call create hash function
        
            console.log({"path":files,"hashCode":result});

        }).then(()=>{ //build fragments 
            //The files is array, so each. files is the folder name. can handle the folder.
            console.log("%s build...", files);
            execSync(`cd ${files} && npm run build`, { encoding: 'utf-8' });  

        }).then(()=>{// Finish timing

            end = new Date().getTime();
            getBuildTime(start,end);  

        }).catch(err => {
            console.log(err);
        });
    }); 

}

async function readDirectory() {

    let files = await readdir(p)
    const folderPath = files.map(function (file) {
        //return file or folder path
        return path.join(p, file);
    }).filter(function (file) {
        //use sync judge method. The file will add next files array if the file is directory, or not. 
        return fs.statSync(file).isDirectory();
    })
    //check hash.json exist or not
    if (fs.existsSync(hashFile)) {
        // path exists
        console.log("File exists: ", hashFile);
        } 
    else 
        {
            //This is the first pipeline, all fragments will build then hash.json will created.
            console.log(hashFile," does NOT exist, build will start and hash.json will created:");
            // Start timing
            start = new Date().getTime();
            iterateFolders(folderPath,files);

            console.log("IT WILL BE LAST ONE ")
            
        }
}
readDirectory();

埃利·G。

iterateFolders函数中,你需要等待computeMetaHash调用。为此,您可以使用 for 循环而不是调用forEachfolderPath 或更改forEachmap并使用Promise.all.

使用 for 循环方法(同步):

async function iterateFolders(folderPath) {
    for (let files of folderPath) {
        //function takes folder path as inputh
        await computeMetaHash(files).then(result => { //call create hash function
            console.log({"path":files,"hashCode":result});

        }).then(()=>{ //build fragments 
            //The files is array, so each. files is the folder name. can handle the folder.
            console.log("%s build...", files);
            execSync(`cd ${files} && npm run build`, { encoding: 'utf-8' });  

        }).then(()=>{// Finish timing

            end = new Date().getTime();
            getBuildTime(start,end);  

        }).catch(err => {
            console.log(err);
        });
    }
}

使用Promise.all方法(异步):

async function iterateFolders(folderPath) {
    return Promise.all(folderPath.map(function (files) {
        //function takes folder path as inputh
        return computeMetaHash(files).then(result => { //call create hash function
        
            console.log({"path":files,"hashCode":result});

        }).then(()=>{ //build fragments 
            //The files is array, so each. files is the folder name. can handle the folder.
            console.log("%s build...", files);
            execSync(`cd ${files} && npm run build`, { encoding: 'utf-8' });  

        }).then(()=>{// Finish timing

            end = new Date().getTime();
            getBuildTime(start,end);  

        }).catch(err => {
            console.log(err);
        });
    }));
}

如果你愿意,使用 async/await 还可以让你摆脱thencatch两种方法,我相信这会让阅读和理解更容易一些。
这是使用该Promise.all方法的示例

async function iterateFolders(folderPath) {
  return Promise.all(folderPath.map(async (files) => {
      try {
          const result = await computeMetaHash(files);
          console.log({ path: files, hashCode: result });

          // build fragments

          //The files is array, so each. files is the folder name. can handle the folder.
          console.log('%s build...', files);
          execSync(`cd ${files} && npm run build`, { encoding: 'utf-8' });

          
          // Finish timing
          const end = Date.now();
          getBuildTime(start, end);
          
      } catch(err) {
          console.log(err);
      }
  }));
}

您可能还想查看 for await... of

注意:iterateFolders当它被调用时你还需要等待readDirectory

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章