简体   繁体   English

嵌套 Promise.all 异步/等待 map

[英]Nested Promise.all async/await map

I encountered a nested for loop with await operations inside them like below:我遇到了一个嵌套的 for 循环,其中包含等待操作,如下所示:

    async handleProjects (projects) {
        for (let i = 0; i < projects.rows.length; i++) {
            projects.rows[i].owner = await this.userProvider.serialize(projects.rows[i].owner);
            for (let j = 0; j < projects.rows[i].collaborators.length; j++) {
                const collaborator = await this.userProvider.serialize(projects.rows[i].collaborators[j].email);
                if (collaborator) {
                    projects.rows[i].collaborators[j].name = collaborator.name;
                    delete projects.rows[i].collaborators[j].role;
                }
            }
        }
        return projects;
    }

1. the code above is run in sequence correct? 1.上面的代码是按顺序运行的吗?

2. to improve the performance I want to use promise.all like below, but some how the run time its about the same and some times the promise.all is even longer. 2.提高性能我想使用 promise.all 如下所示,但有些运行时间大致相同,有时 promise.all 甚至更长。 Where is my mistake on this?我的错误在哪里?

    async handleProject (projects) {
        await Promise.all(projects.rows.map(async (row) => {
            console.log(row);
            row.owner = await this.userProvider.serialize(row.owner);
            return await Promise.all(row.collaborators.map(async (collaborator) => {
                const collaboratorObj = await this.userProvider.serialize(collaborator.email);
                if (collaboratorObj) {
                    collaborator.name = collaboratorObj.name;
                    delete collaborator.role;
                }
            }));
        }));
        return projects;
    }

Let's take a look using timeouts to simulate your asynchronous calls.让我们看一下使用超时来模拟您的异步调用。

This code is equivalent to your first example, before you made your optimizations.在您进行优化之前,此代码等效于您的第一个示例。 Notice how there's only ever a single promise pending at any given moment:请注意在任何给定时刻只有一个 promise 待处理:

 let serializeAndCache = owner => { console.log(`Starting: ${owner}`); let prm = new Promise(r => setTimeout(r, 2000)); prm.then(() => console.log(`Finished: ${owner}`)); return prm; }; let project = { rows: [ { owner: 'owner1', collaborators: [ { name: null, email: 'collab1@row1.com' }, { name: null, email: 'collab2@row1.com' }, { name: null, email: 'collab3@row1.com' }, { name: null, email: 'collab4@row1.com' } ] }, { owner: 'owner2', collaborators: [ { name: null, email: 'collab1@row2.com' }, { name: null, email: 'collab2@row2.com' }, { name: null, email: 'collab3@row2.com' }, { name: null, email: 'collab4@row2.com' } ] }, { owner: 'owner3', collaborators: [ { name: null, email: 'collab1@row3.com' }, { name: null, email: 'collab2@row3.com' }, { name: null, email: 'collab3@row3.com' }, { name: null, email: 'collab4@row3.com' } ] } ] }; (async () => { for (let row of project.rows) { row.owner = await serializeAndCache(row.owner); for (let collaborator of row.collaborators) { let c = await serializeAndCache(collaborator.email); if (;c) continue. collaborator.name = c;name. delete collaborator;role; } } })();

And this code is equivalent to your optimized version:这段代码相当于你的优化版本:

 let serializeAndCache = owner => { console.log(`Starting: ${owner}`); let prm = new Promise(r => setTimeout(r, 2000)); prm.then(() => console.log(`Finished: ${owner}`)); return prm; }; let project = { rows: [ { owner: 'owner1', collaborators: [ { name: null, email: 'collab1@row1.com' }, { name: null, email: 'collab2@row1.com' }, { name: null, email: 'collab3@row1.com' }, { name: null, email: 'collab4@row1.com' } ] }, { owner: 'owner2', collaborators: [ { name: null, email: 'collab1@row2.com' }, { name: null, email: 'collab2@row2.com' }, { name: null, email: 'collab3@row2.com' }, { name: null, email: 'collab4@row2.com' } ] }, { owner: 'owner3', collaborators: [ { name: null, email: 'collab1@row3.com' }, { name: null, email: 'collab2@row3.com' }, { name: null, email: 'collab3@row3.com' }, { name: null, email: 'collab4@row3.com' } ] } ] }; (async () => { await Promise.all(project.rows.map(async row => { row.owner = await serializeAndCache(row.owner); return Promise.all(row.collaborators.map(async collab => { let c = await serializeAndCache(collab.email); if (c) { collab.name = c.name; delete collab.role; } })); })); })();

As you can see, many promises are pending all at once (and overall the code finishes more quickly).如您所见,许多 Promise 都同时处于待处理状态(总体而言,代码完成得更快)。 Your optimization seems like it's working!您的优化似乎奏效了! I can only assume that whatever logic lies behind serializeAndCache behaves poorly when it is flooded by many calls all at once.我只能假设serializeAndCache背后的任何逻辑在同时被许多调用淹没时表现不佳。 This seems to be the only explanation for poor performance.这似乎是性能不佳的唯一解释。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM