嵌套 Promise.all 异步/等待映射

我遇到了一个嵌套的 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. 上面的代码是按顺序运行的吗?


2. 为了提高性能我想使用 promise.all 如下所示,但有些运行时间大致相同,有些时候 promise.all 甚至更长。我的错误在哪里?


    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;

    }


慕容森
浏览 231回答 1
1回答

叮当猫咪

让我们看一下使用超时来模拟您的异步调用。在您进行优化之前,此代码等效于您的第一个示例。请注意在任何给定时刻只有一个承诺待处理:let serializeAndCache = owner => {&nbsp; console.log(`Starting: ${owner}`);&nbsp; let prm = new Promise(r => setTimeout(r, 2000));&nbsp; prm.then(() => console.log(`Finished: ${owner}`));&nbsp; return prm;};let project = {&nbsp; rows: [&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; owner: 'owner1',&nbsp; &nbsp; &nbsp; collaborators: [&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab1@row1.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab2@row1.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab3@row1.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab4@row1.com' }&nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; owner: 'owner2',&nbsp; &nbsp; &nbsp; collaborators: [&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab1@row2.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab2@row2.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab3@row2.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab4@row2.com' }&nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; owner: 'owner3',&nbsp; &nbsp; &nbsp; collaborators: [&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab1@row3.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab2@row3.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab3@row3.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab4@row3.com' }&nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; }&nbsp; ]};(async () => {&nbsp; for (let row of project.rows) {&nbsp; &nbsp; row.owner = await serializeAndCache(row.owner);&nbsp; &nbsp; for (let collaborator of row.collaborators) {&nbsp; &nbsp; &nbsp; let c = await serializeAndCache(collaborator.email);&nbsp; &nbsp; &nbsp; if (!c) continue;&nbsp; &nbsp; &nbsp; collaborator.name = c.name;&nbsp; &nbsp; &nbsp; delete collaborator.role;&nbsp; &nbsp; }&nbsp; }})();这段代码相当于你的优化版本:let serializeAndCache = owner => {&nbsp; console.log(`Starting: ${owner}`);&nbsp; let prm = new Promise(r => setTimeout(r, 2000));&nbsp; prm.then(() => console.log(`Finished: ${owner}`));&nbsp; return prm;};let project = {&nbsp; rows: [&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; owner: 'owner1',&nbsp; &nbsp; &nbsp; collaborators: [&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab1@row1.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab2@row1.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab3@row1.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab4@row1.com' }&nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; owner: 'owner2',&nbsp; &nbsp; &nbsp; collaborators: [&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab1@row2.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab2@row2.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab3@row2.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab4@row2.com' }&nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; owner: 'owner3',&nbsp; &nbsp; &nbsp; collaborators: [&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab1@row3.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab2@row3.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab3@row3.com' },&nbsp; &nbsp; &nbsp; &nbsp; { name: null, email: 'collab4@row3.com' }&nbsp; &nbsp; &nbsp; ]&nbsp; &nbsp; }&nbsp; ]};(async () => {&nbsp;&nbsp;&nbsp; await Promise.all(project.rows.map(async row => {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; row.owner = await serializeAndCache(row.owner);&nbsp; &nbsp; return Promise.all(row.collaborators.map(async collab => {&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; let c = await serializeAndCache(collab.email);&nbsp; &nbsp; &nbsp; if (c) {&nbsp; &nbsp; &nbsp; &nbsp; collab.name = c.name;&nbsp; &nbsp; &nbsp; &nbsp; delete collab.role;&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; }));&nbsp; &nbsp;&nbsp;&nbsp; }));&nbsp;&nbsp;})();如您所见,许多 Promise 都同时处于待处理状态(总体而言,代码完成得更快)。您的优化似乎奏效了!我只能假设背后的任何逻辑serializeAndCache在同时被许多调用淹没时表现不佳。这似乎是性能不佳的唯一解释。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript