将异步和同步工作与异步/等待和/或 javascript 中的承诺混合在一起

She*_*ork 1 javascript promise async-await

更新:我认为我对 async/await 的问题比链接的建议更微妙,并更新了问题的标题,希望能更好地反映这一点。我特别关心如何开始一些可能需要一段时间的异步工作——但不会影响需要按顺序发生的大部分页面逻辑——然后等待异步工作完成,然后再继续页面逻辑的一个子集,依赖于异步逻辑。答案基本上是相同的 ( await Promise.all),但对我的问题的公认答案提供的清晰度比链接的答案更有价值(在使用之前将时序逻辑抽象为自己的异步函数await Promise.all)。

我很难确定这在 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()
  }
});
Run Code Online (Sandbox Code Playgroud)

我熟悉 javascript 中的 async/await 和 promises,但我还没有看到他们有能力完成这类事情的任何演示——我觉得像代码气味一样——设置间隔或超时来检查用于在我想确保asynchronousSetup()在触发之前完成的一些公共变量的初始化executeTask4()

如果我可以这样做,那将是非常甜蜜的:

// ...Same initial code as above.

const initialized = asynchronousSetup();

// ...Same intervening code as above.

if (await initialized) {
  executeTask4();
}
Run Code Online (Sandbox Code Playgroud)

假设它asynchronousSetup()被适当地装饰了async

async function asynchronousSetup() {
  // Logic of asynchronousSetup()
}
Run Code Online (Sandbox Code Playgroud)

但我以前试过没有成功。

谢谢,很抱歉,如果这是一个明显的问题;我的搜索或代码实验都没有运气。我有一种感觉,一旦有人指出如何实现这一点,我就会感到非常愚蠢……但我会接受;在我的理解中,这感觉像是一个很大的障碍,在我可以编写产生良好 UX 的高性能 javascript 之前,我需要克服它;p

rfe*_*tag 5

如果我正确地关注您,则您必须同时执行 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()
});
Run Code Online (Sandbox Code Playgroud)

这假设您的所有任务都是异步的,或者返回 Promises。