【每日一题】请实现一个 cacheRequest 方法

人生苦短,总需要一点仪式感。比如学前端~
请实现一个 cacheRequest 方法,保证发出多次同一个 ajax 请求时都能拿到的数据,而实际上只发出一次请求。
我的思路:
/* 准备一个缓存map,key为请求条件,值为第一次请求的响应结果。后续请求条件相同,直接返回map内的对应结果,不再发起请求。
cacheRequestMap = {
  'get-api/request_api/01': {
    request: {},
    response: data
  }
} */
import axios from 'axios';
let cacheRequestMap = {}
function cacheRequest({
  url,
  type,
  params
}) {
  let key = type + url
  return new Promise((res, rej) => {
    if(cacheRequestMap[key]) {
      res(cacheRequestMap[key].response)
    } else {
      axios[type]({
        url,
        params
      })
      .then((data) => {
        cacheRequestMap[key].response = data
        res(data)
      })
      .catch((err) => {
        rej(err)
      })
    }
  })
}
// 调用方式
cacheRequest({
  url: '/request_api/01',
  type: 'get',
  params: ''
})
.then((data) => {
})
.catch((err) => {
})
参考答案
const request = (url, option) =>
  new Promise((res) => {
    setTimeout(() => {
      res({ data: option });
    }, 2000);
  });
const cache = new Map();
const cacheRequest = (url, option) => {
  let key = `${url}:${option.method}`;
  if (cache.has(key)) {
    if (cache.get(key).status === "pending") {
      return cache.get(key).myWait;
    }
    return Promise.resolve(cache.get(key).data);
  } else {
    // 无缓存,发起真实请求
    let requestApi = request(url, option);
    cache.set(key, { status: "pending", myWait: requestApi });
    return requestApi
      .then((res) => {
        // console.log(cache)
        cache.set(key, { status: "success", data: res });
        // console.log(cache)
        return Promise.resolve(res);
      })
      .catch((err) => {
        cache.set(key, { status: "fail", data: err });
        Promise.reject(err);
      });
  }
};
实现原理
cache 构建 Map,用作缓存数据,把 URL 作为 key,用来判断是否来自同一个请求
请求的更多参数可传入 option,例如 get,data…
每次请求检查缓存,有的话就返回缓存,没有的话发起请求
请求成功后,保存数据到 cache 并返回,失败则弹框提示
特殊情况,如果请求在 pending 状态,则返回该请求继续等待
代码中 ajax 请求用 setTimeout()函数代替,可自行封装 request 函数

让我们一起携手同走前端路!

评论
