这个场景属于一种性能优化吧,面试中也可能会问到你。
话不多说直接上代码

复制代码
  1. <!DOCTYPE html>
  2.  
  3. <html lang=”en”>
  4.  
  5. <head>
  6.  
  7. <meta charset=”UTF-8″ />
  8.  
  9. <meta name=”viewport” content=”width=device-width, initial-scale=1.0″ />
  10.  
  11. <title>Document</title>
  12.  
  13. </head>
  14.  
  15. <body>
  16.  
  17. <h4>Fetch</h4>
  18.  
  19. <p>
  20.  
  21. 如何实现一个缓存机制,使得在Web开发中,当多次发起相同的AJAX请求时,能够保证每次都能获取到数据,但实际上只发送一次请求到服务器,请用
  22.  
  23. JS 实现该方法
  24.  
  25. </p>
  26.  
  27. <div>
  28.  
  29. <button id=”btn”>点击发送</button>
  30.  
  31. </div>
  32.  
  33. <script>
  34.  
  35. const cache = {};

  36. function fetchData(url) {

  37. // 有缓存

  38. if (cache[url]) {

  39. //Promise.resolve() 是 JavaScript 内置的一个方法,用于创建一个立即被解析(fulfill)的 Promise 对象

  40. // return Promise.resolve(cache[url]);

  41. return cache[url];

  42. } else {

  43. // 没有缓存,发起 AJAX 请求

  44. //fetch() 是一个 JavaScript 内置的 API,用于发送 HTTP 请求并获取响应。

  45. return fetch(url)

  46. .then((response) => {

  47. // 将请求得到的数据存入缓存,

  48. // response 它只是一个 HTTP 响应,而不是真的 JSON。

  49. // json()这个方法会异步读取响应体,并且尝试将其解析为 JSON 格式。

  50. if (response.ok) cache[url] = response.json();

  51. return cache[url];

  52. })

  53. .catch((error) => {

  54. console.error(“Error fetching data:”, error);

  55. });

  56. }

  57. }

  58. //addEventListener(“click”, () => {})这是给选定的元素添加事件监听器的方法

  59. document.getElementById(“btn”).addEventListener(“click”, () => {

  60. fetchData(“https://api.realworld.io/api/tags”).then((data) => {

  61. console.log(“Data:”, data);

  62. });

  63. });

  64. </script>

  65. </body>

  66. </html>

这个代码就是我在面试中回答的结果,但是后面面试官又问了另一个问题,
如果接口请求时间比较长,还没返回结果又调用了请求方法,怎么还是只发起一次请求,复用第一次请求的结果?
这个问题我当时想到的是用定时器,具体的操作方法我没有写,但是应该会有一些问题。
现在我推荐的是另一种方法,是直接返回第一次调用的promise,上代码!

复制代码
  1. <!DOCTYPE html>
  2.  
  3. <html lang=”en”>
  4.  
  5. <head>
  6.  
  7. <meta charset=”UTF-8″ />
  8.  
  9. <meta name=”viewport” content=”width=device-width, initial-scale=1.0″ />
  10.  
  11. <title>Document</title>
  12.  
  13. </head>
  14.  
  15. <body>
  16.  
  17. <h4>Fetch</h4>
  18.  
  19. <p>
  20.  
  21. 如何实现一个缓存机制,使得在Web开发中,当多次发起相同的AJAX请求时,能够保证每次都能获取到数据,但实际上只发送一次请求到服务器,请用
  22.  
  23. JS 实现该方法
  24.  
  25. </p>
  26.  
  27. <div>
  28.  
  29. <button id=”btn”>点击发送</button>
  30.  
  31. </div>
  32.  
  33. <script>
  34.  
  35. const cache = {};

  36. function fetchData(url) {

  37. console.log(cache, cache[url], cache”);

  38. // 有缓存且数据已经准备好

  39. if (cache[url] && cache[url].data) {

  40. return Promise.resolve(cache[url].data);

  41. } else if (cache[url] && cache[url].promise) {

  42. // 有缓存但数据还在请求中,返回之前的请求 promise

  43. console.log(cache[url].promise, cache[url].promise”);

  44. return cache[url].promise;

  45. } else {

  46. // 没有缓存,发起新的请求

  47. const fetchPromise = fetch(url)

  48. .then((response) => response.json())

  49. .then((data) => {

  50. // 将请求得到的数据存入缓存

  51. cache[url].data = data;

  52. return data;

  53. })

  54. .catch((error) => {

  55. console.error(“Error fetching data:”, error);

  56. });

  57. // 将 promise 存入缓存

  58. cache[url] = { promise: fetchPromise };

  59. return fetchPromise;

  60. }

  61. }

  62. //addEventListener(“click”, () => {})这是给选定的元素添加事件监听器的方法

  63. document.getElementById(“btn”).addEventListener(“click”, () => {

  64. fetchData(“https://api.realworld.io/api/tags”).then((data) => {

  65. console.log(“Data:”, data);

  66. });

  67. });

  68. </script>

  69. </body>

  70. </html>

将第一次请求的promise存储起来,在请求还没成功的时候,返回promise对象,相当于返回的就是第一次请求的内容结果