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
如果我正确地关注您,则您必须同时执行 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。