zoukankan      html  css  js  c++  java
  • 使用JavaScript发布订阅设计模式实现Ajax请求节流

    1. 说明一下主要逻辑

      当我们发送多个请求时使用的时同一个接口,并且这个接口支持多个参数获取多个条数据,而我们不想要每次请求一条数据就发送一条请求

      而是在指定的时间段类发送一次请求,得到一些数据,然后把这些数据 返回到对应的发起请求的地方

    2. 使用场景

      比如像QQ聊天会有一个联系人列表,这个列表每个联系人会有一个头像,我们可以通过一个接口获取指定的用户的头像图片链接,也可以一次性获取多个头像链接,只需要有多个用户ID即可

      但是一般都是会在联系人列表渲染时,每渲染一个联系人列表发送一次请求,这样就会发送多次请求,造成不必要的浪费,我们选择获取联系人列表之后只发送一次请求就行

    3. 实现一个简单的发布订阅者模式

    let event = {
        events:[],
        /**
         * 添加订阅
         * @param  {[String]}   event     [description]
         * @param  {Function}     fn         [description]
         * @return {[undefined]}        [description]
         */
        on(event, fn){
            if(!event || !fn) return;
            let hasEvent = this.hasEvent(event);
            if(hasEvent){
                hasEvent.handler.push(fn);
            } else {
                this.events.push({
                    type: event,
                    handler: [ fn ]
                });
            }
        },
        /**
         * 发布订阅
         * @param  {[String]}    event     [description]
         * @param  {...[any]}     arg       [description]
         * @return {[undefined]}        [description]
         */
        emit(event, ...arg){
            let hasEvent = this.hasEvent(event);
            if(hasEvent){
                hasEvent.handler.forEach(fn => fn(...arg));
            } else {
                console.log('该事件还没有订阅');
            }
        },
        /**
         * 判断该事件是否已经注册
         * @param  {[String]}      event     [description]
         * @return {Boolean}               [description]
         */
        hasEvent(event){
            return this.events.find(ele=>ele.type === event);
        },
        /**
         * 移除订阅事件
         * @param  {[type]}   event [description]
         * @param  {Function} fn    [description]
         * @return {[type]}         [description]
         */
        removeEvent(event, fn){
            if(event && fn){
                let eve = this.hasEvent(event);
                if(eve){
                    eve.handler.splice(eve.handler.indexOf(fn), 1);
                }
            }
            if(event && !fn){
                for(let i = 0; i< this.events.length; i++){
                    if(this.events[i].type === event){
                        this.events.splice(i, 1);
                        break;
                    }
                }
            }
        }
    }

    3. 书写Ajax请求函数

    function ajax(url, data){
        clearTimeout(ajax.timer);
        if(!ajax.dataArr){
            ajax.dataArr = [];
        }
        ajax.dataArr.push(data);
        ajax.timer = setTimeout(()=>{ // 限制在300毫秒内的请求会只请求一次
            fetch(url, {
                method: 'POST',
                body: JSON.stringify(ajax.dataArr)
            }).then(res=>res.json()).then(res=>{
                event.emit('send', res);
            })
        }, 300);
        return new Promise((resolve, reject)=>{
            event.on('send', (res) => {
                resolve(res.filter(item=>item.id == data.id)[0]);
            });
        })
    }

    4. 准备一个模拟json数据的 data.json 文件

    [{
        "id": 1,
        "content": "文本内容11111"
    },{
        "id": 2,
        "content": "文本内容22222"
    },{
        "id": 3,
        "content": "文本内容33333"
    },{
        "id": 4,
        "content": "文本内容44444"
    },{
        "id": 5,
        "content": "文本内容55555"
    },{
        "id": 6,
        "content": "文本内容66666"
    },{
        "id": 7,
        "content": "文本内容77777"
    },{
        "id": 8,
        "content": "文本内容88888"
    }]

    5.发送Ajax请求

    for(let i = 1; i<=8; i++){
        ajax('./data.json', {id: i}).then(res=>{
            console.log(res);
        })
    }

    6. 返回的数据

  • 相关阅读:
    Java高级项目实战02:客户关系管理系统CRM系统模块分析与介绍
    Java高级项目实战之CRM系统01:CRM系统概念和分类、企业项目开发流程
    Java字符串编码
    Java线程有哪些不太为人所知的技巧与用法?
    捕获异常之使用SLF4J和Logback
    捕获异常之使用Log4j
    Idea 热部署插件JRebel 安装与环境配置-上海尚学堂Java培训
    Java变量常量声明和定义
    LeetCode239 滑动窗口最大值
    LeetCode347. 前 K 个高频元素
  • 原文地址:https://www.cnblogs.com/litings/p/13862612.html
Copyright © 2011-2022 走看看