小程序之事件总线

Posted roy-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小程序之事件总线相关的知识,希望对你有一定的参考价值。

一.主要原理

我把一些会被多个页面调用的事件放到一个集合里面,以事件名称为key,以事件及其回调函数的数组为值。大概的形式如下。

events=“event_name1”:[[o11,callback11],[o12,callback12]],"event_name2":[[o21,callback21],[o22,callback22]]

然后其他的页面就可以从这个池子(集合)里面通过事件名称找到对应的事件元素,拿到他的callback函数,进行调用了。

二.主要代码

事件总线的主要代码如下:

 1 let events = ;
 2 
 3 const on = function (name, self, callback) 
 4     const tuple = [self, callback];
 5     const callbacks = events[name];
 6     if (Array.isArray(callbacks)) 
 7         callbacks.push(tuple);
 8     
 9     else 
10         events[name] = [tuple];
11     
12 
13 
14 const remove = function (name, self) 
15     const callbacks = events[name];
16     if (Array.isArray(callbacks)) 
17         events[name] = callbacks.filter((tuple) => 
18             return tuple[0] != self;
19         )
20     
21 
22 
23 const emit = function (name, data) 
24     const callbacks = events[name];
25     if (Array.isArray(callbacks)) 
26         callbacks.map((tuple) => 
27             const self = tuple[0];
28             const callback = tuple[1];
29             callback.call(self, data);
30         )
31     
32 
33 
34 module.exports = 
35     on: on,
36     remove: remove,
37     emit: emit
38 

首先我们定义了一个events对象,它的结构就是我们上面所说的那样。然后我们写了三个函数,分别是on,remove,emit。分别分别代表将事件注册,事件卸载,还有调用事件。

在on方法中,我们先检查当前name所对应的事件是否已存在(通过Array.isArray方法来判断其是否是数组,因为当callbacks为[]或者undifined的时候,该方法返回false).如果不存在,则将当前的tuple置为二维数组中的第一个数组元素。

在remove方法中,我们先通过name获取到其对应的二维数组callbacks,还是先通过Array.isArray判断该二维数组是否存在,如果存在,开始遍历该二维数组,并且过滤掉第一个元素为self的数组。(这边使用到了数组的filter方法,该方法通过回调函数会保留判断为true的元素,剔除掉判断为false的元素)。然后我们把过滤后的二维数组重新赋值给events[name]。这样就实现了事件的卸载。

最重要的是emit函数,这也是我们做事件总线的主要原因:我们同样通过name来获取二维数组,然后执行该二维数组中的每一个回调函数,此处通过call方法来实现。

三.使用方法

 1 onShow: function () 
 2     const _this = this;
 3     const key = app.config.amapkey;
 4     const initAmap = new amap.AMapWX( key: key );
 5     events.on(‘locationData‘, this, function (data) 
 6       const origin = data.longitude + ‘,‘ + data.latitude;
 7       const destination = app.globalData.destination;
 8       initAmap.getDrivingRoute(
 9         origin: origin,
10         destination: destination,
11         success: function (data) 
12           let points = [];
13           if (data.paths && data.paths[0] && data.paths[0].steps) 
14             const steps = data.paths[0].steps;
15             for (var i = 0; i < steps.length; i++) 
16               const poLen = steps[i].polyline.split(‘;‘);
17               for (var j = 0; j < poLen.length; j++) 
18                 points.push(
19                   longitude: parseFloat(poLen[j].split(‘,‘)[0]),
20                   latitude: parseFloat(poLen[j].split(‘,‘)[1])
21                 )
22               
23             
24           
25           if (data.paths[0] && data.paths[0].distance) 
26             _this.setData(
27               distance: data.paths[0].distance + ‘米‘
28             );
29           
30           _this.setData(
31             polyline: [
32               points: points,
33               color: "#0091ff",
34               width: 1,
35               dottedLine: true
36             ]
37           );
38         
39       )
40       console.log(destination)
41 
42       const markersArray = [
43         iconPath: ‘/resources/image/yipin.png‘,
44         id: ‘pickUpAddress‘,
45         longitude: parseFloat(destination.split(‘,‘)[0]),
46         latitude: parseFloat(destination.split(‘,‘)[1]),
47         width: 25,
48         height: 25,
49         title: ‘自提地点‘,
50         label: 
51           content: ‘厦门出口加工区\n海景东路18号2楼‘,
52           bgColor: ‘#fff‘,
53           padding: ‘5‘,
54           borderRadius: ‘3‘
55         
56       , 
57         id: ‘myLocation‘,
58         longitude: data.longitude,
59         latitude: data.latitude,
60       ]
61       _this.setData(
62         markersArray, markersArray
63       )
64     )
65   ,

上述代码的第5行,注册了一个事件,名称叫做locationData,并且传入参数this,指代当前页面的page对象,还有一个匿名回调函数。

接下来看如何调用这个事件

1   sendLocation: function () 
2     const _this = this;
3     wx.getLocation(
4       type: ‘wgs84‘,
5       success: function (res) 
6         events.emit(‘locationData‘, res);
7       
8     )
9   ,

调用emit函数,传入事件名称locationData,并且参数res(对应回调函数的参数data)

事件销毁方法如下:

1   onUnload: function () 
2     const _this = this;
3     clearInterval(_this.data.locationTimer)
4     events.remove(‘locationData‘, this);
5   ,

 

以上是关于小程序之事件总线的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序-发布订阅-事件总线-页面组件通信

微信小程序-发布订阅-事件总线-页面组件通信

Spark2.1.0之源码分析——事件总线

风险洞察之事件总线的探索与演进

风险洞察之事件总线的探索与演进

ABP之事件总线