You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中async await函数未互相等待执行问题求解

问题根因
  • 你定义的iterateFolders虽然标记为async,但内部用forEach遍历执行异步任务,forEach本身不会等待异步回调执行完成,且函数没有返回所有异步任务的Promise集合,外部无法感知其执行进度
  • 在readDirectory中调用iterateFolders时没有加await,即使内部逻辑正确,也不会等待其执行完成就会走后续代码
修复方案

1. 重写iterateFolders函数

替换forEach为支持异步等待的for...of循环(默认串行执行目录处理,避免多个npm run build同时抢占资源),同时收集所有哈希结果方便后续生成JSON文件,函数最终返回Promise供外部等待。
同步修改getBuildTime为返回Promise的版本,方便感知日志写入完成状态:

// 修改后返回Promise的计时日志函数
function getBuildTime(start,end) {
    let time = (end - start);
    let buildTime = `${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()} Build time: ${time} ms \n`   
    // 用fs的promise接口返回Promise
    return fsp.writeFile('build-time.log', buildTime);
}

// 修改后的iterateFolders
async function iterateFolders(folderPath) {
    const hashList = []; // 收集所有哈希值,后续生成JSON用
    // 串行处理每个目录
    for (const files of folderPath) {
        try {
            const result = await computeMetaHash(files);
            console.log({"path":files,"hashCode":result});
            hashList.push({path: files, hashCode: result});

            // 构建碎片
            console.log("%s build...", files);
            execSync(`cd ${files} && npm run build`, { encoding: 'utf-8' });  

            // 完成计时
            const end = new Date().getTime();
            await getBuildTime(start, end);
        } catch (err) {
            console.log(err);
        }
    }
    return hashList; // 返回所有哈希结果给后续逻辑使用
}

2. 修改readDirectory调用逻辑

调用iterateFolders时加上await,等待所有任务执行完成后再跑后续逻辑,拿到返回的哈希列表即可生成目标JSON文件:

async function readDirectory() {
    let files = await readdir(p)
    const folderPath = files.map(function (file) {
        return path.join(p, file);
    }).filter(function (file) {
        return fs.statSync(file).isDirectory();
    })
    if (fs.existsSync(hashFile)) {
        console.log("File exists: ", hashFile);
    } else {
        console.log(hashFile," does NOT exist, build will start and hash.json will created:");
        start = new Date().getTime();
        // 加await等待所有目录处理完成,同时拿到哈希列表
        const hashList = await iterateFolders(folderPath, files);
        // 生成哈希JSON文件
        await fsp.writeFile(hashFile, JSON.stringify(hashList, null, 2));
        console.log("IT WILL BE LAST ONE ")
    }
}
可选优化:并行处理目录

如果设备资源足够,想要并行处理所有目录提升速度,可以把iterateFolders中的for...of替换为Promise.all实现并发处理:

async function iterateFolders(folderPath) {
    const taskList = folderPath.map(async files => {
        const result = await computeMetaHash(files);
        console.log({"path":files,"hashCode":result});
        console.log("%s build...", files);
        execSync(`cd ${files} && npm run build`, { encoding: 'utf-8' });  
        const end = new Date().getTime();
        await getBuildTime(start,end);
        return {path: files, hashCode: result};
    })
    return Promise.all(taskList);
}

内容的提问来源于stack exchange,提问作者noobinmath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 19:54:00