【每日一题】请实现一个 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 函数
让我们一起携手同走前端路!
评论