为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕容森 2022-10-08 10:35:51
我遇到了一个嵌套的 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;    }
查看完整描述

1 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

让我们看一下使用超时来模拟您的异步调用。

在您进行优化之前,此代码等效于您的第一个示例。请注意在任何给定时刻只有一个承诺待处理:

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;

    }

  }

})();

这段代码相当于你的优化版本:

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;

      }

      

    }));

    

  }));

  

})();

如您所见,许多 Promise 都同时处于待处理状态(总体而言,代码完成得更快)。您的优化似乎奏效了!我只能假设背后的任何逻辑serializeAndCache在同时被许多调用淹没时表现不佳。这似乎是性能不佳的唯一解释。



查看完整回答
反对 回复 2022-10-08
  • 1 回答
  • 0 关注
  • 230 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号