首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用Promise.all替换多个异步/等待调用?

如何用Promise.all替换多个异步/等待调用?
EN

Stack Overflow用户
提问于 2020-12-08 10:04:25
回答 2查看 109关注 0票数 2

我有下面的try/catch代码块,它进行了3个不同的api调用。以下代码运行良好,但当firstData具有大型数据集时,它会花费大量时间来执行。

代码语言:javascript
复制
try {
    const firstData = await myservice1.myservice1Func();

    for(let i=0; i<firstData.total; i++){
        const hostName = firstData.rows[i]['hostname'];
        if (hostName !== null && firstData.rows[i]['myservice1Id'] !== null) {
            const aRes = await myService2(hostName);
            firstData.rows[i]['mylist'] =
                    aRes[0].dataValues;
        }
        if (hostName !== null && firstData.rows[i]['type'].includes('type1')) {
            const oRes = await myService3(hostName);
            firstData.rows[i]['ores'] = oRes.rows[0];
        }
        if (hostName !== null && firstData.rows[i]['type'].includes('type2')) {
            const vRes = await myService4(hostName);
            firstData.rows[i]['vRes'] = vRes.rows[0];
        }
    }
    return firstData;
} catch (err) {
    console.log(err);
}

这里,

代码语言:javascript
复制
const firstData = 
{
  "total": 2,
  "rows": [
    {
      "hostname": "abc.com",
      "ipAddress": "11.11.11.11",
      "myservice1Id": "ee0f77c9-ef15",
      "type": "type1"
    },
    {
      "hostname": "cde.com",
      "ipAddress": "12.12.12.12",
      "type": "type2",
      "myservice1Id": null
    }
  ]
}   


const aRes = 
[
  {
        "listType": "list1",
        "createdAt": "2020-12-07"
  }
]


const oRes =
{
  "rows": [
    {
      "status": "FAIL"
    }
  ]
}


const vRes =
{
  "rows": [
    {
      "status": "FAIL"
    }
  ]
}

返回的firstData的最终值如下:

代码语言:javascript
复制
{
  "total": 2,
  "rows": [
    {
      "hostname": "abc.com",
      "ipAddress": "11.11.11.11",
      "myservice1Id": "ee0f77c9-ef15",
      "type": "type1",
      "oRes": {
        "status": "PASS"
      },
      "mylist": {
        "listType": "list1",
        "createdAt": "2020-12-07"
      }
    },
    {
      "hostname": "cde.com",
      "ipAddress": "12.12.12.12",
      "type": "type2",
      "myservice1Id": null,
      "vRes": {
        "status": "FAIL"
      }
    }
  ]
}   

这里,需要注意的一件事是,所有3个if blocks都可以并行执行,因为它们彼此独立。我可以使用Promise.allparallel中执行所有的3个if blocks吗?如果是,更新后的代码在使用Promise.all时会是什么样子

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-12-08 10:08:00

最简单的调整是将每个Promise推送到ifs中的一个数组中:

代码语言:javascript
复制
const proms = [];
if (hostName !== null && firstData.rows[i].myservice1Id !== null) {
    proms.push(
      myService2(hostName)
        .then(aRes => firstData.rows[i].mylist = aRes[0].dataValues)
    );
}
// other ifs changed around the same way

await Promise.all(proms);

您还可以通过只执行一次hostName检查来简化代码,这样看起来就像是在遍历整个数组,这可以通过调用迭代器来更容易地完成:

代码语言:javascript
复制
try {
    const firstData = await myservice1.myservice1Func();
    for (const row of firstData.rows) {
        const hostName = row.hostname;
        if (hostName === null) continue;
        const proms = [];
        if (row.myservice1Id !== null) {
            proms.push(
                myService2(hostName)
                    .then(aRes => row.mylist = aRes[0].dataValues)
            );
        }
        // etc
票数 2
EN

Stack Overflow用户

发布于 2020-12-08 10:45:09

您好,您有一些代码修改,

代码语言:javascript
复制
for(let i=0; i<firstData.total; i++){
    const hostName = firstData.rows[i]['hostname'];

     //check if condition inside the service and return a null (a promise)
     Promise.all([myService2(hostName), myService3(hostName), myService4(hostName)]).then((values) => {
        console.log(values);
        //[resutl1,null,result3]
     });
}

现在的问题是,你必须等到最慢的迭代才能完成,你可以使用promise pool use,@supercharge/promise-pool来解决这个问题

MDN Promise Medium Blog Source

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65192058

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档