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

JS多层异步回调全部完成后仅单次调用指定函数的实现方案

需求说明

遍历长度不固定的对象数组travelDataGroups[{}],在forEach()循环中调用异步方法newUser(),该方法内部还需调用另一个异步方法loadOtherUsersPayRate()。需要在所有回调执行完成、循环结束后调用makeWorkbookDownloadObj(),但该方法仅能调用一次,否则会损坏生成的对象。

原问题代码

myGroupWorkReportObj.travelDataGroups.forEach( travelerData =>
{
    // 为当前用户添加薪资标准
    const someUser = new User( travelerData.employeeId , function()
    {
        // 为当前用户和项目添加薪资标准
        const projectId = travelerData.projectId;
            
        const payRate = loadOtherUsersPayRate( projectId, someUser )
            .then( payRate =>
            {
                // 创建差旅数据行
                const rowOfData = [
                    travelerData.firstName,
                    travelerData.lastName,
                    travelerData.travelHours,
                    financial( payRate.pay / 2 )
                ];

                // 将数据行推入表格
                thisSheet.data.push( rowOfData );

                // 需要在所有回调完成后仅调用一次
                // makeWorkbookDownloadObj( workbookObj );
        });
});

最终可运行代码

核心实现逻辑是将每个异步流程包装为Promise,存入数组后通过Promise.allSettled等待所有异步执行完成,再统一调用目标方法:

const userPromises = [];

// 将User类的实例化回调包装为Promise
var aUserPromise = ( travelerData ) =>
{
    return new Promise( ( resolve, reject ) =>
    {
        new User( travelerData.employeeId, ( someUserObj ) =>
        {
            // 加载对应用户和项目的薪资标准
            loadOtherUsersPayRate( travelerData.projectId, someUserObj )
            .then( payRate =>
            {
                // 创建差旅数据行
                const rowOfData = [
                    travelerData.firstName,
                    travelerData.lastName,
                    travelerData.travelHours,
                    financial( payRate.pay / 2 )
                ];

                // 将数据行推入表格
                thisSheet.data.push( rowOfData );

                resolve();
            } );
        } );
    } );
};

myGroupWorkReportObj.travelDataGroups.forEach(( travelerData ) =>
{
    // 执行异步函数,将Promise实例存入数组
    var myRun = aUserPromise( travelerData );
    userPromises.push( myRun );
});

// 等待所有异步执行完成后,仅调用一次下载对象生成方法
Promise.allSettled( userPromises )
.then( ()=>
{
    makeWorkbookDownloadObj( workbookObj )
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:54:04