Specifi c задание на каждый асин c вызов и обещание ждать всех - PullRequest
2 голосов
/ 12 февраля 2020

Безопасно ли использовать асинхронные операции в javascript следующим образом:

async coolFunction(users) {
  const firstPromise = findPrivilegesInOneDbAsync();
  const secondPromise = findPrivilegesInSecondDbAsync();
//LABEL_1
  firstPromise.then(privilege=> {
    users.forEach(user => {
      if(user.privCode === privilege.code) {
        user.privileges.push(privilege);
      }
    }
  }
//LABEL_2
  secondPromise.then(privilege=> {
    users.forEach(user => {
      if(user.altPrivCode === privilege.differentCode) {
        user.privileges.push(privilege);
        user.hasAlternativePrvis = true;
      }
    }
  }
//LABEL_3
  Promise.all([firstPromise, secondPromise]).then(() => {
    console.log("DONE!");
    //do something
  })
}

Вопрос в том, гарантируется ли выполнение обратного вызова LABEL_3 - Promise.all после первого и второго обещания (порядок в тех два конечно не имеет значения) обратные вызовы сделаны?

1 Ответ

3 голосов
/ 12 февраля 2020

... гарантируется ли, что обратный вызов LABEL_3 - Promise.all будет выполнен после выполнения первого и второго обещаний (порядок в этих двух, конечно, не имеет значения) обратных вызовов?

Да, это так. Обработчики исполнения обещания вызываются в порядке регистрации. Так как ваши предыдущие были зарегистрированы до ваших Promise.all, они будут запущены первыми.

Пример:

function delay(ms, ...args) {
    return new Promise(resolve => {
        setTimeout(resolve, ms, ...args);
    });
}

const promise = delay(800);
promise.then(() => {
    console.log("first");
});

promise.then(() => {
    console.log("second");
});

Но, вероятно, было бы более идиоматически c использовать вместо этого обещания, возвращаемые then:

async coolFunction(users) {
  const firstPromise = findPrivilegesInOneDbAsync();
  const secondPromise = findPrivilegesInSecondDbAsync();
  Promise.all([
      firstPromise.then(privilege=> {
        users.forEach(user => {
          if(user.privCode === privilege.code) {
            user.privileges.push(privilege);
          }
        }
      },
      secondPromise.then(privilege=> {
        users.forEach(user => {
          if(user.altPrivCode === privilege.differentCode) {
            user.privileges.push(privilege);
            user.hasAlternativePrvis = true;
          }
        }
      }
  ])
  .then(() => {
    console.log("DONE!");
    //do something
  });
}

Это также имело бы Преимущество ожидания любых обещаний, возвращаемых этими обработчиками выполнения, перед выполнением логики «done» c.


Вероятно, стоит отметить, что нет причин для того, чтобы этот метод был async, если вы ' мы собираемся делать подобные вещи параллельно и использовать обработчики .then вместо await. Вы могли бы сделать это, однако, чтобы сохранить обработку первых двух вещей параллельно, но ждать, пока они оба завершатся sh:

async coolFunction(users) {
  const firstPromise = findPrivilegesInOneDbAsync();
  const secondPromise = findPrivilegesInSecondDbAsync();
  await Promise.all([
      firstPromise.then(privilege=> {
        users.forEach(user => {
          if(user.privCode === privilege.code) {
            user.privileges.push(privilege);
          }
        }
      },
      secondPromise.then(privilege=> {
        users.forEach(user => {
          if(user.altPrivCode === privilege.differentCode) {
            user.privileges.push(privilege);
            user.hasAlternativePrvis = true;
          }
        }
      }
  ])
  console.log("DONE!");
  //do something
}

Это также будет ждать любых обещаний, возвращаемых этими обработчиками выполнения перед выполнением логики "done" c.

...