使用函数式编程实现接口缓存
假设我们需要请求一个接口
1 2 3 4 5 6 7 8 9 10 11 12 13
   | const get = (url, params) => Promise.resolve(params);
  const getData = (params) => get("/api", params);
  const appendDiv = (text) => {   const div = document.createElement("div");   div.innerText = text;   document.body.appendChild(div); };
  getData({ q: 123 }).then((data) => {   appendDiv(JSON.stringify(data)); });
   | 
 
使用缓存优化性能
现在为了性能优化,我们需要对性能优化需要做缓存处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | 
  const cacheMap = {};
  const getKey = (url, params) =>   JSON.stringify({     __url: url,     ...params,   });
  const params = { q: 123 }; const key = getKey("/api", params);
  const handleData = (data) => appendDiv(JSON.stringify(data));
  if (cacheMap[key]) {   handleData(cacheMap[key]); } else {   getData(params).then((data) => {     cacheMap[key] = data;     handleData(data);   }); }
 
  | 
 
利用代理模式分离缓存和业务逻辑
我们可以利用代理模式的思路,将缓存和请求分离开来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | const getDataProxy = async (params) => {   const key = getKey("/api", params);   if (cacheMap[key]) {     return cacheMap[key];   }   return getData(params); };
  const handleDataProxy = (params, data) => {   const key = getKey("/api", params);   cacheMap[key] = data;   handleData(data); };
  getDataProxy(params).then((data) => handleDataProxy(params, data));
  | 
 
使用 currying 和高阶函数复用代码
虽然我们现在把当前请求的缓存和请求分离开来,但是只限定当前请求,并不能通用化
我们使用高阶函数来实现代码复用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   | import { compose, tap, curry } from "lodash/fp";
 
  const ifElse = (flag, firstFun, secondFun) => {   return flag ? firstFun : secondFun; };
  const getCache = (key) => cacheMap[key];
  const setCache = curry((key, data) => (cacheMap[key] = data));
  const proxyRequest = curry((url, request, params) => {   const key = getKey(url, params);   return ifElse(getCache(key), () => getCache(key), request)(params); });
  const proxyHandleData = curry((url, handleData, params, data) => {   const key = getKey(url, params);   setCache(key, data);   handleData(data); });
  const getDataProxy = proxyRequest("/api", getData); const handleDataProxy = proxyHandleData("/api", handleData);
  getDataProxy(params).then(handleDataProxy(params));
  |