Эффективное использование async/await

Я знаю await в петлях крайне не рекомендуется. Но я застрял в конкретном случае, я не могу понять, как это сделать эффективно. Я хочу окончательный вывод переменной values как это

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

Ниже приведен фрагмент моей текущей реализации.

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)
}

Я могу запихнуть все обещания в один массив и ждать всех. но я бы потерял след, какое значение обещания принадлежит какому идентификатору задания. Хотя разделение всего массива await по каждому 4-му индексу даст мне то, что я хочу, я ищу еще лучшие альтернативы.

3 ответа

Решение

Если вы хотите выполнять все ваши запросы параллельно, вы действительно не будете использовать await в петле. Однако вам не нужно помещать все свои обещания в один и тот же массив, а затем разбивать их на каждые 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;
}

Я думаю, что вы делаете это эффективно. Вы пользуетесь асинхронным потенциалом. Я не думаю, что было бы более эффективно, если бы вы собрали все обещания в один массив и подождали их всех. В этом случае я не вижу способа восстановить связь между идентификатором задания и результатом каждого обещания. Это правда, что вы можете реорганизовать все повторяющиеся строки, но это касается чистого кода, а не эффективности. Это может быть первый подход:

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);
}

Может быть, вы можете использовать Q-библиотеку для своих обещаний здесь. С помощью этой библиотеки вы можете легко комбинировать и связывать свои обещания.

Надеюсь это поможет!

С уважением.

Другие вопросы по тегам