js实现请求缓存方法

作者: 王希桐 | 来源:发表于2020-04-07 13:09 被阅读0次

    在面试的时候遇到的一个面试题感觉比较有意思就来记录一下

    题目如下:

    实现一个方法在接收到同一个url请求时不重复请求后端直接返回结果

    思考过程:

    1、定一个一个对象用来存储对应请求url下的状态、和返回结果还有一个执行队列。结构如下

    let obj = {
        url1: {
            status: 'suc',
            data: {
                a: 1,
                b: 2
            },
            queue: []
        },
        url2: {
            status: 'suc',
            data: {
                a: 1,
                b: 2
            },
            queue: []
        }
    };
    

    2、写一个cacheRequest的函数接收三个参数url、sucCallback、failCallback,需要注意请求延时的情况,比如第一个url请求进来之后还没有返回结构但是第二个相同的url又请求过来了

    具体代码

    // 实现一个函数来模拟请求
    function resquest(url, suc, fail) {
        if (Math.random() * 10 > 2) {
            setTimeout(() => {
                console.log(url + '|' + 'suc');
                suc('sucess');
            }, Math.random() * 5 * 1000);
        } else {
            setTimeout(() => {
                console.log(url + '|' + 'fail');
                fail('fail');
            }, Math.random() * 5 * 1000);
        }
    }
    
    let objArr = {};
    function cacheRequest(url, sucCb, failCb) {
        if (objArr[url]) { // 已经请求过,直接返回结果
            if (objArr[url].status === 'suc') { // 请求过,并成功
                sucCb(objArr[url].data);
            } else if (objArr[url].status === 'fail') { // 请求过,但失败
                failCb(objArr[url].data);
            } else { // 已请求,但未返回结果,将未执行函数放入队列
                if (objArr[url].queue && objArr[url].queue.length > 0) {
                    objArr[url].queue.push({'suc': sucCb, 'fail': failCb});
                } else {
                    objArr[url].queue = [{'suc': sucCb, 'fail': failCb}];
                }
            }
        } else {
            objArr[url] = {
                data: '',
                status: ''
            };
            resquest(url, data => {
                objArr[url].data = data;
                objArr[url].status = 'suc';
                sucCb(data);
                if (objArr[url].queue && objArr[url].queue.length > 0) { // 检测并处理队列中滞留的函数
                    for (let i = 0; i < objArr[url].queue.length; i++) {
                        objArr[url].queue[i].suc(data);
                    }
                    objArr[url].queue = []; // 清空队列
                }
            }, err => {
                objArr[url].data = err;
                objArr[url].status = 'fail';
                failCb(err);
                if (objArr[url].queue && objArr[url].queue.length > 0) { // 检测并处理队列中滞留的函数
                    for (let i = 0; i < objArr[url].queue.length; i++) {
                        objArr[url].queue[i].fail(err);
                    }
                    objArr[url].queue = []; // 清空队列
                }
            });
        }
    }
    
    cacheRequest('1.com', data => {
        console.log(data);
    }, err => {
        console.log(err);
    });
    cacheRequest('1.com', data => {
        console.log(data);
    }, err => {
        console.log(err);
    });
    cacheRequest('1.com', data => {
        console.log(data);
    }, err => {
        console.log(err);
    });
    cacheRequest('1.com', data => {
        console.log(data);
    }, err => {
        console.log(err);
    });
    cacheRequest('1.com', data => {
        console.log(data);
    }, err => {
        console.log(err);
    });
    cacheRequest('2.com', data => {
        console.log(data);
    }, err => {
        console.log(err);
    });
    cacheRequest('2.com', data => {
        console.log(data);
    }, err => {
        console.log(err);
    });
    cacheRequest('3.com', data => {
        console.log(data);
    }, err => {
        console.log(err);
    });
    
    

    下图是测试用例结果


    相关文章

      网友评论

        本文标题:js实现请求缓存方法

        本文链接:https://www.haomeiwen.com/subject/keggphtx.html