Смешивание асинхронной и синхронной работы с async / await и / или обещаниями в javascript - PullRequest
1 голос
/ 02 апреля 2020

ОБНОВЛЕНИЕ: Я думаю, что у меня есть вопрос относительно async / await, немного более нюансированный, чем связанное предложение, и я обновил название вопроса, чтобы, надеюсь, лучше отразить это. Меня особенно интересует, как запустить некоторую асинхронную работу, которая потенциально может занять некоторое время - но это не влияет на большую часть логики страницы c, которая должна происходить последовательно, - а затем дождаться завершения асинхронной работы, прежде чем продвигаясь вперед с подмножеством логик страницы c, которые действительно полагаются на асинхронный лог c. В конечном итоге ответ оказывается практически таким же (await Promise.all), но ясность, обеспеченная принятым ответом на мой вопрос, была для меня более ценной, чем связанный ответ (перед использованием * абстрагируйте последовательные логики c в свою собственную асинхронную функцию) 1006 *).

У меня проблемы с выяснением, возможно ли это в javascript (блок комментариев, помеченный «XXX» в начале, - это код, с которым я борюсь (притворись, что задачи 1-4 должны выполняться по порядку и не могут быть распараллелены)):

document.addEventListener('DOMContentLoaded', () => {
  // Kick off some asynchronous piece of work that potentially takes some 
  // time (for instance, opening and upgrading an indexedDB) but that should
  // not hold up other work that should happen in the meantime (ie: executing
  // tasks 1-3).
  asynchronousSetup(); // 1000 - 1500 ms of work

  // Do a bunch of other stuff that should happen in sequence and as quickly
  // as possible (to enable meaningful user interaction in the client).
  executeTask1(); // 300 - 400 ms of work
  executeTask2(); // 300 - 400 ms of work
  executeTask3(); // 300 - 400 ms of work

  // XXX Wait for completion of asynchronousSetup() before proceeding with
  // any additional work that is also necessary for meaningful user
  // interaction in the client, but that requires that the work done in
  // asynchronousSetup() is completely finished.
  if (/* asynchronousSetup() complete */) {
    executeTask4(); // Relies on work done in tasks 1-3 and asynchronousSetup()
  }
});

Я знаком с async / await и обещаниями в javascript, но я не видел никаких демонстраций их способности чтобы выполнить sh такого рода вещи без - то, что мне кажется запахом кода - установка интервала или тайм-аута для проверки инициализации некоторой общей переменной в точке, где я хочу убедиться, что asynchronousSetup() завершено до стрельба executeTask4().

Было бы очень мило, если бы я мог сделать:

// ...Same initial code as above.

const initialized = asynchronousSetup();

// ...Same intervening code as above.

if (await initialized) {
  executeTask4();
}

при условии, что asynchronousSetup() был соответственно украшен Тед с async:

async function asynchronousSetup() {
  // Logic of asynchronousSetup()
}

, но я пробовал это раньше безуспешно.

Спасибо, извините, если это очевидно; Мне не повезло ни в моих поисках, ни в моих экспериментах с кодом. У меня такое чувство, что я буду чувствовать себя очень глупо, как только кто-то укажет, как этого добиться ... но я постараюсь сделать все возможное; в моем понимании это существенное препятствие, которое мне нужно преодолеть, прежде чем я смогу написать производительность javascript, что приведет к хорошему UX; p

1 Ответ

5 голосов
/ 02 апреля 2020

Если я правильно следую за вами, вы должны выполнить asyncSetup и 3 задачи одновременно (но эти 3 задачи должны быть выполнены по порядку). Только после того, как все 4 из этих задач выполнены, вы хотите перейти к последнему заданию. Кажется, что-то вроде этого делает то, что вы просите:

//Provide an async function that does your 3 tasks in the correct order
const doTasks = async () => {
  await executeTask1(); // 300 - 400 ms of work
  await executeTask2(); // 300 - 400 ms of work
  await executeTask3(); // 300 - 400 ms of work
}
document.addEventListener('DOMContentLoaded', async () => {
  //Do the setup and the tasks concurrently
  await Promise.all([asynchronousSetup(), doTasks()])
  //Once all of the previous tasks are done, do the last task
  executeTask4()
});

Это предполагает, что все ваши задачи все асин c, или что обещания возврата.

...