自定义事件解决重复请求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 相关文章推荐
ExtJS Window 最小化的一种方法
Nov 18 Javascript
节点的插入之append()和appendTo()的用法介绍
Jan 13 Javascript
检查输入的是否是数字使用keyCode配合onkeypress事件
Jan 23 Javascript
js阻止默认浏览器行为与冒泡行为的实现代码
May 15 Javascript
JavaScript中的call和apply的用途以及区别
Jan 11 Javascript
JS获取短信验证码倒计时的实现代码
May 22 Javascript
JS原型继承四步曲及原型继承图一览
Nov 28 Javascript
用vscode开发vue应用的方法步骤
May 06 Javascript
微信小程序防止多次点击跳转(函数节流)
Sep 19 Javascript
在Layui中操作数据表格,给指定单元格添加事件示例
Oct 26 Javascript
ES6如何用一句代码实现函数的柯里化
Jan 18 Javascript
MutationObserver在页面水印实现起到的作用详解
Jul 07 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下图片文字混合水印与缩略图实现代码
2009/12/11 PHP
PHP STRING 陷阱原理说明
2010/07/24 PHP
浅谈php中mysql与mysqli的区别分析
2013/06/10 PHP
PHP邮件群发机实现代码
2016/02/16 PHP
详解PHP匿名函数与注意事项
2016/03/29 PHP
PHP实现二维数组按某列进行排序的方法
2016/11/18 PHP
php使用parse_str实现查询字符串解析到变量中的方法
2017/02/17 PHP
javascript针对DOM的应用实例(一)
2012/04/15 Javascript
JS实现支持多选的遍历下拉列表代码
2015/08/20 Javascript
jQuery插件之Tocify动态节点目录菜单生成器附源码下载
2016/01/08 Javascript
JS中Eval解析JSON字符串的一个小问题
2016/02/21 Javascript
理解javascript正则表达式
2016/03/08 Javascript
JavaScript中自带的 reduce()方法使用示例详解
2016/08/10 Javascript
AngularJs bootstrap搭载前台框架——基础页面
2016/09/01 Javascript
鼠标经过出现气泡框的简单实例
2017/03/17 Javascript
JavaScript实现三级级联特效
2017/11/05 Javascript
vue中slot(插槽)的介绍与使用
2018/11/12 Javascript
vscode下vue项目中eslint的使用方法
2019/01/13 Javascript
vue.js iview打包上线后字体图标不显示解决办法
2020/01/20 Javascript
javascript实现倒计时效果
2020/02/17 Javascript
[49:31]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第二场 1月29日
2021/03/11 DOTA
Python脚本简单实现打开默认浏览器登录人人和打开QQ的方法
2016/04/12 Python
详解Python的Twisted框架中reactor事件管理器的用法
2016/05/25 Python
Python中创建字典的几种方法总结(推荐)
2017/04/27 Python
Django框架教程之正则表达式URL误区详解
2018/01/28 Python
TensorFlow神经网络优化策略学习
2018/03/09 Python
django认证系统实现自定义权限管理的方法
2018/07/16 Python
Django-Rest-Framework 权限管理源码浅析(小结)
2018/11/12 Python
Python面向对象基础入门之编码细节与注意事项
2018/12/11 Python
python xpath获取页面注释的方法
2019/01/14 Python
浅谈python新式类和旧式类区别
2019/04/26 Python
anaconda安装pytorch1.7.1和torchvision0.8.2的方法(亲测可用)
2021/02/01 Python
abstract 可以和 virtual 一起使用吗?可以和 override 一起使用吗?
2012/10/15 面试题
应急管理培训方案
2014/06/12 职场文书
村主任当选感言
2015/08/01 职场文书
干货:我将这样书写我的演讲稿!
2019/05/09 职场文书