预加载异步数据的好模式是什么?

问题描述 投票:0回答:1

我正在 Zendesk 中构建一些功能,主要使用普通 JS(jQuery 也可用),并且我有一个按钮需要运行 API 调用以首先获取一些数据,然后才能完成其“真正”的工作。但异步数据是静态的——它永远不会根据用户或会话改变——所以我想在页面加载后立即预加载它,以节省以后的时间。但该按钮不应假定数据已加载,即使 90% 的情况下都已加载。我不想设置任何烦人的竞争条件。

过去,在类似的场景中,我通过默认禁用按钮并在异步数据加载后启用它来处理此问题。但我只是想知道是否有更好的模式。

javascript xmlhttprequest
1个回答
1
投票

当您使用现代 API(如

fetch
)异步加载数据时,您将使用 Promises 来管理异步性。

当您开始加载 Promise 时,将其存储在缓存中。

然后,当你想使用它时(例如,通过单击按钮),你只需

await
存储的 Promise 即可。如果预缓存已完成,它将已处于已解决状态。如果仍处于待处理状态,则操作将照常暂停,直到数据可用。


如果您使用的是较旧的 API(例如

XMLHttpRequest
),那么您可以手动将操作包装在 Promise 中。


const fetchData = () => {
  return new Promise((resolve) => {
    console.log("Simulating a long running data fetching operation");
    let percent_done = 0;

    (function fetchChunk() {
      percent_done += 10;
      console.log(`Loaded ${percent_done}%`);
      if (percent_done >= 100) resolve("Here is your data");
      else setTimeout(fetchChunk, 1000);
    })();
  });
};

const cache = fetchData();

const logData = async() => {
  const clickTime = new Date();
  const data = await cache;
  const now = new Date();
  console.log(`Data was "${data}" from click at ${clickTime.toLocaleTimeString()} (time now is ${now.toLocaleTimeString()})`);
};

document.querySelector("button").addEventListener('click', logData);
<button>Click me</button>

© www.soinside.com 2019 - 2024. All rights reserved.