自定义事件解决重复请求BUG的问题


Posted in Javascript onJuly 11, 2017

现在,组件化开发还是比较流行的,毕竟其优点相当突出。最近在开发一个组件的时候,遇到了一个很有意思的BUG。。。

BUG的背景

最近在开发一个组件,好不容易开发好了转测试。然后,测试给我提了一个这样的bug,orz...

自定义事件解决重复请求BUG的问题

因为是一个组件,最大的好处就是可以随处复用,随处使用,然而,当一个页面用了多个组件,只有最后一个生效的时候,这个组件就没有什么意义了。。。

BUG原因查找

这个组件的初始数据来源的接口是固定的,也就是说,页面内的所有这个组件在初始化的时候都会发出同样的请求,这里的请求是jsonp的方式,所以回调函数是绑定在window上的一个函数,但是在页面中window只有一个,所以在回调处理的时候,要处理的组件内的相应的数据只指向最后一个组件。所以导致多个同样的组件在同一个页面中,只有最后一个组件能在取得数据之后顺利渲染出来。

BUG解决思路

最主要就是要将每次请求的callback存储起来,这样就可以保证callback中对组件数据的处理不是只指向最后一个。其次,既然是一样的请求,当然不希望会发出两次以上啦,即一个页面发出的每一个请求都是唯一的。

BUG解决方案

想到了发布订阅者模式的自定义事件,可以写这样的一个模块,每次请求发出前判断一下之前是否有相同的模块已经发出了,如果没有则缓存callback发出请求,如果有相同的请求已经发出了,那么检查一下这个发出的请求是否已经完成了,如果没有则继续缓存callback等待,如果请求已经发出并且已经完成则直接处理callback。在请求第一次回来后,发出广播,把之前缓存的callback都执行一次。

自定义事件详情

定义一个模块,里面有n个以回调函数命名的事件对象,每个对象有在被初始化的时候,定义其状态state,对应的callback数组,请求回到的数据data。每次调用该模块,首先检查对应的cbName是否被初始化,然后检查其state。根据state做相应的操作并改变state的值。state的值有3中,分别为init、loading、loaded。即初始化、请求中、请求完成。处于请求完成状态时才能执行相应的回调。

具体如下:

define('wq.getData', function (require, exports, module) {
  var ls = require('loadJs');
   
  var cache = {};
  cache.init = function(cb,cbName,url){
    if(!cache[cbName]){
      cache[cbName] = {};
      cache[cbName].state = 'init';
      cache[cbName].cbs = [];
      cache[cbName].data = [];
    }
    cache.on(cb,cbName,url);
  }
  cache.on = function(cb,cbName,url){
    if(cache[cbName].state == 'loaded'){
      cb(cache[cbName].data)
    }else if(cache[cbName].state == 'loading'){
      cache[cbName].cbs.push(cb)
    }else if(cache[cbName].state == 'init'){
      cache[cbName].cbs.push(cb);
      cache[cbName].state = 'loading';
      cache.fetch(cb,cbName,url);
    }
  }
  cache.broadcast = function(cbName){
    cache[cbName].cbs.forEach(function(cb){
      cb(cache[cbName].data)
    });
  }
  cache.checkLoaded = function(cbName){
    if(cache[cbName].data[0]){
      cache[cbName].state = 'loaded';
      cache.broadcast(cbName);
    }
  }
  cache.fetch = function(cb,cbName,url){
    ls.loadScript({
      url: url,
      charset: 'utf-8',
      handleError:function(func, args, context,errorObj){
        console.log(_errlogText + context);
        cache[cbName].data[0] = {};
        cache.checkLoaded(cbName);
      }
    });
    if(window.cbName) return;
    window[cbName] = function(json){
      cache[cbName].data[0] = json;
      cache.checkLoaded(cbName);
    }
  }
 
  exports.getData = function(cb,cbName,url){
    cache.init(cb,cbName,url);
  } 
 
})

完美解决问题,每个回调都不会遗漏或者被覆盖……

扩展思路

该模块可通用于处理一个页面内同一个请求的情况。还可以扩展到处理一些需要2个请求以上完成才执行某个回调的情况。类似于Promose的情况。这个时候可以规定,每个data[0]装的是固定的对应接口的数据,data[2]对应另一个,一次类推。不过这样就要遍历到每一项都为true的时候才执行回调。而且对应关系比较容易混乱,再扩展就不如直接用Promise来处理了。。。

以上这篇自定义事件解决重复请求BUG的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 构造函数在表单提交过程中修改数据
May 25 Javascript
Bootstrap框架下下拉框select搜索功能
Mar 26 Javascript
jQuery实现页面滚动时智能浮动定位
Jan 08 Javascript
基于node.js依赖express解析post请求四种数据格式
Feb 13 Javascript
浅谈使用React.setState需要注意的三点
Dec 18 Javascript
原生JS实现的轮播图功能详解
Aug 06 Javascript
详解Angular5/Angular6项目如何添加热更新(HMR)功能
Oct 10 Javascript
浅析Vue.js中v-bind v-model的使用和区别
Dec 04 Javascript
Vue使用mixin分发组件的可复用功能
Sep 01 Javascript
jQuery实现图片随机切换、抽奖功能(实例代码)
Oct 23 jQuery
PHP读取远程txt文档到数组并实现遍历
Aug 25 Javascript
js+cavans实现图片滑块验证
Sep 29 Javascript
关于js中的鼠标事件总结
Jul 11 #Javascript
vue音乐播放器插件vue-aplayer的配置及其使用实例详解
Jul 10 #Javascript
angular学习之从零搭建一个angular4.0项目
Jul 10 #Javascript
在Vue中使用echarts的实例代码(3种图)
Jul 10 #Javascript
jquery.validate.js 多个相同name的处理方式
Jul 10 #jQuery
Angular2生命周期钩子函数的详细介绍
Jul 10 #Javascript
使用Webpack提高Vue.js应用的方式汇总(四种)
Jul 10 #Javascript
You might like
php为什么选mysql作为数据库? Mysql 创建用户方法
2007/07/02 PHP
发款php蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
php实现基于微信公众平台开发SDK(demo)扩展的方法
2014/12/22 PHP
php获取字符串中各个字符出现次数的方法
2015/02/23 PHP
简单的pgsql pdo php操作类实现代码
2016/08/25 PHP
js 发个判断字符串是否为符合标准的函数
2009/04/27 Javascript
基于jQuery实现的水平和垂直居中的div窗口
2011/08/08 Javascript
AngularJS使用angular-formly进行表单验证
2015/12/27 Javascript
浅析Bootstrap组件之面板组件
2016/05/04 Javascript
jQuery插件Flexslider实现图片轮播、图文结合滑动切换效果
2020/04/16 Javascript
JavaScript 计算笛卡尔积实例详解
2016/12/02 Javascript
微信小程序 缓存(本地缓存、异步缓存、同步缓存)详解
2017/01/17 Javascript
jQuery实现页面倒计时并刷新效果
2017/03/13 Javascript
在JS中如何把毫秒转换成规定的日期时间格式实例
2017/05/11 Javascript
解决vue页面DOM操作不生效的问题
2018/03/17 Javascript
详解js常用分割取字符串的方法
2019/05/15 Javascript
bootstrap+spring boot实现面包屑导航功能(前端代码)
2019/10/09 Javascript
[06:10]6.81新信使新套装!给你一个炫酷的DOTA2
2014/05/06 DOTA
python写xml文件的操作实例
2014/10/05 Python
python从网络读取图片并直接进行处理的方法
2015/05/22 Python
Python中用altzone()方法处理时区的教程
2015/05/22 Python
Python爬虫:通过关键字爬取百度图片
2017/02/17 Python
Python实现常见的几种加密算法(MD5,SHA-1,HMAC,DES/AES,RSA和ECC)
2020/05/09 Python
python实现图书馆抢座(自动预约)功能的示例代码
2020/09/29 Python
如何利用Python matplotlib绘制雷达图
2020/12/21 Python
顶级宝石首饰网络零售商:Angara
2016/10/25 全球购物
车工岗位职责
2013/11/26 职场文书
医院竞聘演讲稿
2014/05/16 职场文书
关于安全的标语
2014/06/10 职场文书
党员教师四风自我剖析材料
2014/09/30 职场文书
分居协议书范本
2014/11/03 职场文书
在职证明范本
2015/06/15 职场文书
2015年高三教学工作总结
2015/07/21 职场文书
2015年政治教研组工作总结
2015/07/22 职场文书
用Python实现Newton插值法
2021/04/17 Python
Python+SeaTable实现计算两个日期间的工作日天数
2022/07/07 Python