【问题标题】:efficient use of async/await高效使用 async/await
【发布时间】:2018-06-04 22:24:14
【问题描述】:

我知道 await 非常不鼓励在循环中使用。但我被困在一个特定的案例上,我无法弄清楚如何有效地做到这一点。我想要像这样的变量values 的最终输出

{
  jobId1: [[..], [..], [..], [..]],
  jobId2: [[..], [..], [..], [..]] // list goes on
}

下面的 sn-p 代表我当前的实现。

for (let jb of jobList ) {
  const subArray = []
  const rel1 = new Parse.Relation(jb, 'applicants')
  const rel2 = new Parse.Relation(jb, 'shortlisted')
  const rel3 = new Parse.Relation(jb, 'hired')
  const rel4 = new Parse.Relation(jb, 'rejected')
  subArray.push(rel1.query().containedIn('objectId', uniqUserIds).select('objectId').find())
  subArray.push(rel2.query().containedIn('objectId', uniqUserIds).select('objectId').find())
  subArray.push(rel3.query().containedIn('objectId', uniqUserIds).select('objectId').find())
  subArray.push(rel4.query().containedIn('objectId', uniqUserIds).select('objectId').find())

  values[jb.id] = await Promise.all(subArray)
}

我可以将所有的 Promise 推送到一个单独的数组中,然后等待。但我会丢失承诺值属于哪个job id的轨道。尽管将整个 await 数组按每 4 个索引拆分一次可以得到我想要的,但我正在寻找更好的替代方案。

【问题讨论】:

  • but I'd lose out the track which promise value belongs to which job id - 不,你不会......和......最后两行?为什么?对 values[jb.id] 的第一个赋值是没有意义的,因为它被第二个覆盖了
  • + Jaromanda X,据我所知,它用于在未定义的情况下进行初始化。但是我正在编辑 sn-p
  • "我知道 await 在循环中非常不鼓励。" - 不是吗?如果您想要顺序迭代,这正是您要走的路。

标签: javascript node.js parse-server ecmascript-2017


【解决方案1】:

也许您可以使用 Q 库来实现您的承诺 here。 使用这个库,您可以轻松地组合和链接您的 Promise。

希望这会有所帮助!

亲切的问候。

【讨论】:

    【解决方案2】:

    我认为你的做法是有效的。您正在利用异步潜力。如果您将所有承诺放在一个数组中并等待所有承诺放在一起,我认为这不会更有效。在那种情况下,我看不到恢复工作 ID 与每个承诺的结果之间的关联的方法。 的确,您可以重构所有重复的行,但那是关于干净的代码,而不是关于效率。这可能是第一种方法:

    var executeQuery = function(list) {
        const subArray = [];
        for(let element of list) {
           const rel = new Parse.Relation(jb, element);
           subArray.push(rel.query().containedIn('objectId', uniqUserIds).select('objectId').find())
        };
        return subArray;
    }
    
    for (let jb of jobList ) {
        values[jb.id] = values[jb.id] || {};
        var subArray = executeQuery(['applicants', 'shortlisted', 'hired', 'rejected']);
        values[jb.id] = await Promise.all(subArray);
    }
    

    【讨论】:

      【解决方案3】:

      如果您想并行运行所有查询,您确实不会在循环中使用await。但是,您不需要将所有 Promise 放在同一个数组中,然后在每 4 个值处拆分 - 只需使用适当的嵌套结构!

      function query(jb, name) {
        const rel = new Parse.Relation(jb, name);
        return rel.query().containedIn('objectId', uniqUserIds).select('objectId').find();
      }
      async function getValues(jobList) {
        const promises = jobList.map(jb =>
          Promise.all([
            jb.id,
            query(jb, 'applicants'),
            query(jb, 'shortlisted'),
            query(jb, 'hired'),
            query(jb, 'rejected'),
          ])
        );
        const results = await Promise.all(promises);
        const values = {};
        for (const [id, ...res] of results)
          values[id] = res;
        return values;
      }
      

      【讨论】:

      • 很棒的解决方案
      猜你喜欢
      • 1970-01-01
      • 2015-09-20
      • 1970-01-01
      • 1970-01-01
      • 2019-10-04
      • 2020-03-25
      • 2021-06-05
      • 2017-08-23
      • 2021-05-28
      相关资源
      最近更新 更多