【问题标题】:need to find when all callbacks resolved需要找到所有回调何时解决
【发布时间】:2021-09-10 16:47:58
【问题描述】:

下面是我的 javascript 函数中的一个 sn-p。它采用任意大小的对象数组travelDataGroups[{}] 并对其进行迭代。在forEach() 内部我必须调用newUser(),这是异步的,而在内部我必须调用loadOtherUsersPayRate(),这是异步的。
在所有的回调都解决并且循环完成后,我需要调用makeWorkbookDownloadObj(),关键是它只能调用一次,否则会破坏对象。

myGroupWorkReportObj.travelDataGroups.forEach( travelerData =>
{
    // add the pay rate for this user
    const someUser = new User( travelerData.employeeId , function()
    {
        // add the pay rate for this user and project
        const projectId = travelerData.projectId;
            
        const payRate = loadOtherUsersPayRate( projectId, someUser )
            .then( payRate =>
            {
                //create a row of travel data
                const rowOfData = [
                    travelerData.firstName,
                    travelerData.lastName,
                    travelerData.travelHours,
                    financial( payRate.pay / 2 )
                ];

                // push the row of data into the sheet
                thisSheet.data.push( rowOfData );

                // need to only call this once, when all callbacks are resolved
                // makeWorkbookDownloadObj( workbookObj );
        });
});

编辑最终工作代码:

const userPromises = [];

// wrap the User class in a Promise
var aUserPromise = ( travelerData ) =>
{
    return new Promise( ( resolve, reject ) =>
    // new User( employeeId, ( someUser ) =>
    {
        // return new Promise( ( resolve, reject ) =>
        new User( travelerData.employeeId, ( someUserObj ) =>
        {
            // add the pay rate for this user and project
            loadOtherUsersPayRate( travelerData.projectId, someUserObj )
            .then( payRate =>
            {
                //create a row of travel data
                const rowOfData = [
                    travelerData.firstName,
                    travelerData.lastName,
                    travelerData.travelHours,
                    financial( payRate.pay / 2 )
                ];

                // push the row of data into the sheet
                thisSheet.data.push( rowOfData );

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

myGroupWorkReportObj.travelDataGroups.forEach(( travelerData ) =>
{
    // add the pay rate for this user
     ** this line would push the function, but not execute it (until later),
     ** so did in two lines as below
    // userPromises.push(aUserPromise(travelerData)); 

    var myRun = aUserPromise( travelerData );
    userPromises.push( myRun );
});

Promise.allSettled( userPromises )
.then( ()=>
{
    makeWorkbookDownloadObj( workbookObj )
});

【问题讨论】:

  • 那里必须成为这个的欺骗目标。使用map,返回承诺,并在结果数组上使用Promise.all。 (假设您希望所有工作并行完成。)
  • 尝试映射你的数组并构造多个promise,然后使用Promise.All。
  • @NizarZizoune 我的大脑不理解如何在此使用map。你能举个例子吗?

标签: javascript arrays callback


【解决方案1】:

按照您的评论并使用 Promise ALL 和先前答案使用的相同模式:

const userPromises = [];
myGroupWorkReportObj.travelDataGroups.forEach( travelerData =>
    {
// add the pay rate for this user
        userPromises.push(new User( travelerData.employeeId , function()
        {
            // add the pay rate for this user and project
            const projectId = travelerData.projectId;
    
            const payRate = loadOtherUsersPayRate( projectId, someUser )
                .then( payRate =>
                {
                    //create a row of travel data
                    const rowOfData = [
                        travelerData.firstName,
                        travelerData.lastName,
                        travelerData.travelHours,
                        financial( payRate.pay / 2 )
                    ];
    
                    // push the row of data into the sheet
                    thisSheet.data.push( rowOfData );
                })
        }));
    });
Promise.all(userPromises).then(() => {
    makeWorkbookDownloadObj( workbookObj );
});

真正需要解决的承诺是用户的创造。

【讨论】:

  • 这让我很接近,但我的 User 是经典的回调风格,所以我必须将它包装在 Promise 中才能让它工作。我更新了我的 OP 以显示工作结果。
  • 哦,是的,我确实错过了那个。
【解决方案2】:

我这样做 - 使用 Promise.all - 请参阅此处获取文档:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

请注意,下面的代码未经测试,但您可以查看如何操作:

  • 创建承诺数组
  • 在该数组上调用 Promise.all

const promises = []

promises.push(
    loadOtherUsersPayRate( projectId, someUser )
            .then( payRate =>
            {
                //create a row of travel data
                const rowOfData = [
                    travelerData.firstName,
                    travelerData.lastName,
                    travelerData.travelHours,
                    financial( payRate.pay / 2 )
                ];

                // push the row of data into the sheet
                thisSheet.data.push( rowOfData );

                // need to only call this once, when all callbacks are resolved
                // makeWorkbookDownloadObj( workbookObj );
        });
)

Promise.all(promises).then( ()= > makeWorkbookDownloadObj( workbookObj ));

【讨论】:

  • 这几乎可以工作。但我有 new User 函数,它也是异步的。所以两层异步。我尝试将 Promise 提升一个级别,但我遇到了某种语法错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-07
  • 1970-01-01
  • 2020-09-11
相关资源
最近更新 更多