自定义事件解决重复请求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 相关文章推荐
js模拟弹出效果代码修正版
Aug 07 Javascript
Mootools 1.2教程 事件处理
Sep 15 Javascript
javascript 时间比较实现代码
Oct 28 Javascript
JQuery.ajax传递中文参数的解决方法 推荐
Mar 28 Javascript
从零开始学习Node.js系列教程之基于connect和express框架的多页面实现数学运算示例
Apr 13 Javascript
vue项目打包部署_nginx代理访问方法详解
Sep 20 Javascript
小程序server请求微信服务器超时的解决方法
May 21 Javascript
关于layui的下拉搜索框异步加载数据的解决方法
Sep 28 Javascript
Egg Vue SSR 服务端渲染数据请求与asyncData
Nov 24 Javascript
js实现随机圆与矩形功能
Oct 29 Javascript
vant自定义二级菜单操作
Nov 02 Javascript
vue实现列表拖拽排序的示例代码
Apr 08 Vue.js
关于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的错误信息
2006/10/09 PHP
php自动获取目录下的模板的代码
2010/08/08 PHP
PHP使用CURL_MULTI实现多线程采集的例子
2014/07/29 PHP
Yii2中关联查询简单用法示例
2016/08/10 PHP
对php 判断http还是https,以及获得当前url的方法详解
2019/01/15 PHP
PHP实现数组和对象的相互转换操作示例
2019/03/20 PHP
List Information About the Binary Files Used by an Application
2007/06/11 Javascript
jQuery 隔行换色 支持键盘上下键,按Enter选定值
2009/08/02 Javascript
利用javascript实现禁用网页上所有文本框,下拉菜单,多行文本域
2013/12/14 Javascript
jQuery实现个性翻牌效果导航菜单的方法
2015/03/09 Javascript
KnockoutJS 3.X API 第四章之数据控制流component绑定
2016/10/10 Javascript
Vue 实现双向绑定的四种方法
2018/03/16 Javascript
理解Proxy及使用Proxy实现vue数据双向绑定操作
2020/07/18 Javascript
js实现滚动条自动滚动
2020/12/13 Javascript
详解Python的Django框架中manage命令的使用与扩展
2016/04/11 Python
Python实现购物车购物小程序
2018/04/18 Python
Python3.0中普通方法、类方法和静态方法的比较
2019/05/03 Python
Python tkinter三种布局实例详解
2020/01/06 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
2020/01/08 Python
tensorboard显示空白的解决
2020/02/15 Python
selenium判断元素是否存在的两种方法小结
2020/12/07 Python
matplotlib绘制多子图共享鼠标光标的方法示例
2021/01/08 Python
Under Armour安德玛荷兰官网:美国高端运动科技品牌
2019/07/10 全球购物
商得四方公司面试题(gid+)
2014/04/30 面试题
乌鸦喝水教学反思
2014/02/07 职场文书
个人简历中自我评价
2014/02/11 职场文书
测控技术自荐信
2014/06/05 职场文书
田径运动会通讯稿
2014/09/13 职场文书
2014年小学重阳节活动策划方案
2014/09/16 职场文书
2014最新党员批评与自我批评材料
2014/09/24 职场文书
2015年人事专员工作总结
2015/04/29 职场文书
搞笑婚礼主持词开场白
2015/11/24 职场文书
Oracle 数据仓库ETL技术之多表插入语句的示例详解
2021/04/12 Oracle
iPhone13将有八大升级
2021/04/15 数码科技
JavaScript实现班级抽签小程序
2021/05/19 Javascript
MySQL 8.0 之不可见列的基本操作
2021/05/20 MySQL