前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >http请求缓存

http请求缓存

原创
作者头像
剁椒鱼鳞
修改2023-05-30 11:00:10
3770
修改2023-05-30 11:00:10
举报
文章被收录于专栏:前端小学生前端小学生

思路:

  1. 定义一个http的状态map,存储请求的pending和complete,目的是为了解决同一个请求,在同一时间发起多次请求,为了避免发起多次同一个接口,存储status,本次request尚未【success】(非error),不发起下一次同一接口
  2. 定义回调的map,存储请求的回调函数,目的是为了,请求成功之后,触发回调,尤其是同一时间发起多次同一个request,当一个pending时,其他均置于map回调中,当success时,以此触发每个回调
  3. 定义一个返回值map,存储每个request的结果,当下一次发起同一个请求时,去缓存里查找同时返回对应的结果,如果未查到,则发起请求
  4. 定义请求的id,以参数、url以及请求方式当id,以此判断这次请求在缓存中是否有这个id
代码语言:javascript
复制
import { singleton  } from "./singleton";

class Cache {
    statusMap = new Map();
    cacheMap = new Map();
    cbMap = new Map();

    constructor() {
    }
    setCache(request) {
        const cacheKey = this.guidGeneratorRequestKey(request);
        if (this.statusMap.has(cacheKey)) {
            const status = this.statusMap.get(cacheKey);
            if (status === 'complete') {
                return Promise.resolve(this.cacheMap.get(cacheKey));
            }
            if (status === 'pending') {
                return new Promise((resolve, reject) => {
                    if (this.cbMap.has(cacheKey)) {
                        const arr = this.cbMap.get(cacheKey);
                        arr.push({
                            onSuccess: resolve,
                            onFail: reject,
                        })
                        this.cbMap.set(cacheKey, arr)
                    } else {
                        this.cbMap.set(cacheKey, [
                            {
                                onSuccess: resolve,
                                onFail: reject,
                            }
                        ])
                    }
                })
            }
        }
        this.statusMap.set(cacheKey, 'pending');
        return new Promise((resolve, reject) => {
            xx({
                url: request.url,
                method: request.method || 'get',
                header: {

                },
                data: request.params,
                timeout: 10000,
                success: (res) => {
                    console.log('[cache]: params, url, res--setCache:', request.params, request.url, res);
                    const token = res.data.data || '';
                    if (res.status == 200 || res.statusCode == 200) { // iOS: status;Android:statusCode
                        this.statusMap.set(cacheKey, 'complete');
                        this.cacheMap.set(cacheKey, token);
                        resolve(token);
                    } else {
                        this.statusMap.delete(cacheKey)
                        reject(res);
                    }
                    if (this.cbMap.has(cacheKey)) {
                        const arr = this.cbMap.get(cacheKey);
                        for (let list of arr) {
                            list.onSuccess && list.onSuccess(token);
                        }
                        this.cbMap.delete(cacheKey)
                    }
                },
                failure: (error) => {
                    console.error('[cache]: error--setCache:', error);
                    reject(error);
                },
            });
        })
    }
    guidGeneratorRequestKey(config) {
        return `url=${ config.url }&method=${ config.method }&params=${ JSON.stringify(config.params) }`;
    }

}

export default singleton(Cache);

以上为基本demo,,此方法有几处待优化:

  1. 成功回调应返回data,而不是data中的某个字段(本方法为解决每次请求接口都会请求token接口而封装,故只返回了token而已)
  2. 上文提及到,同一时间发起多次同一接口,除第一个真正发起了http请求,其余均被推到回调cache中,问题是,如果第一次请求超时,或者报错,进而导致后续http均不会收到数据,所以该方法应该有重试功能
  3. 在这里没有考虑并发问题,应该考虑下,同时发起大量http请求的问题

上述2、3问题,时间关系,后续优化~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档