RxWX又添新成员

RxWX简介:RxWX是可以让你写出更高效更优雅微信小程序的开源项目,它主要完成了两项工作:将RxJS移植到小程序端和将wx原生API转化成Observable对象。
项目地址:https://github.com/yalishizhude/RxWX
npm模块名:rxjs-wx

感谢开发者的支持和关注,使得RxWX项目不断迭代和进步,新版本得RxWX根据小程序新的API和issue中大家提出的问题,进行了一些优化和修复。

RxWX-seed

虽然RxWX是结构简单、无依赖的第三方JavaScript模块(只有两个js文件),可直接在项目中引用。但是如果有个开箱即用的项目,不但能引入了RxWX,并能给出一些适当的示例代码,在搭建新项目的时候会方便很多。RxWX-seed就是这样的一个项目。

轻量

基于小程序默认初始化项目修改,项目结构基本保持与小程序开发工具提供的默认的初始化项目一致,只包含两个页面——index和logs。

纯粹

相对于小程序默认初始化项目,只在utils目录中引入了RxWX.js和Rx.js。其中Rx.js为RxJS在小程序中的可用版本,而RxWX.js则基于RxJS对小程序全局对象wx的API进行的封装。

规范

将app.js、pages/index/index.js、pages/logs/logs.js业务逻辑中的wx替换成了rxwx对象,对原生调用方式进行了替换,使用封装后的API和操作符来实现原来的逻辑,相当于简单的示例代码。

RxWX-wepy-example与RxWX-example

在上一个版本的RxWX中,示例项目被放入example目录中。虽然这样可以快方便地看示例,但是缺点也很明显:每次通过GitHub下载源码或者通过npm安装rxjs-wx时,将会下载冗余的示例代码,而这部分代码比项目本身提交要大很多。增加了开发者的下载时间,所以决定将示例代码分离成单独地项目。

这里将原生小程序示例拆分成了RxWX-example,在wepy中使用RxWX地示例拆分成了RxWX-wepy-example

RxWX的issue

RxWX项目发布后,GitHub上的issue中提出了几个在README中未提到的,却又有价值的问题,这里补充一下。

终止请求

发起网络请求的API——wx.request在1.4.0版本之后加入了一个新的功能:在调用wx.request之后会返回一个实例,这个实例提供了一个abort函数,用来取消请求。

由于RxWX的request函数返回的是一个Observable对象,所以无法再返回请求实例,但是可以通过Observable对象的unsubscribe函数来取消订阅,从而忽略请求返回的结果,不执行对应的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 原生API
let requestInstance = wx.request({
url: 'xxx',
success: function(res) {
console.log(res.data)
}
})
requestInstance.abort()
// 使用RxWX
let subscription = rxwx.request({
url: 'xxx',
})
.subscribe(data => {
console.log(data)
})
subscription.unsubscribe()

执行效果基本相同,缺点就是无法立即结束小程序的请求。

事件防抖

小程序中绑定事件非常简单,但是有时候我们希望对事件响应逻辑进行特殊处理,例如下面这段代码:

1
2
3
4
5
6
7
8
9
10
<!-- xwml代码 -->
<view bindtap="submit">submit</view>
// js代码
submit() {
// 处理逻辑....
wx.navigateTo({
url: 'xxx/yyy'
})
}
//...

如果你手速够快(或者事件处理逻辑消耗时间较长,造成页面的短暂卡顿),在页面跳转之前进行多次点击的话会发生多次页面跳转,从而缓存多个页面,后退时需要多次点击才能退回到当前页面,这时候需要防抖操作来避免多次触发跳转。

RxJS中就有debounceTime操作符来进行防抖操作,使用RxWX很容以写成如下的代码:

1
2
3
4
5
6
7
8
// js代码
submit() {
rxwx.navigateTo({
url: 'xxx/yyy'
})
.debounceTime(1000) // 1000ms之内只触发一次
.subscribe()
}

但是上面这段代码并不能达到我们想要的效果,多次点击仍会触发多次跳转,因为每次调用submit函数时都会通过rxwx.navigateTo重新创建一个Observable对象,而这个重新创建的Observable对象都会立即发送跳转逻辑,无法重复使用或手动调用。

再看看RxJS在Web页面上的实现。Web页面上可以通过Observable.fromEvent来代替事件注册,同时返回一个新的Observable对象,然后再对其进行防抖操作。例如:

1
2
3
Rx.Observable.fromEvent(document.querySelector('button'), 'click')
.debounceTime(1000)
.subscribe(() => console.log('Clicked!'));

然而在小程序中不能这么写,因为小程序中没有DOM。这时我们可以借助RxJS中另一个重要的对象——Subject,准确地说是使用它生成的实例。

Subject是一种特殊类型的 Observable,它允许将值多播给多个观察者,不过这在我们这个应用中并不重要,相比Observable,它还支持next(发送值)、error(发出错误)和complete(完成发送)函数。我们可以使用next函数来手动发送值。

如果将RxWX的navigateTo返回的Observable对象进行结合,由Subject手动调用即可实现。具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import rxwx, { Rx } from '../../util/RxWX.js';
Page({
navigate: new Rx.Subject(),
onReady() {
Rx.Observable.of().multicast(this.navigate)
.debounceTime(1000)
.switchMap(url => rxwx.navigateTo({
url
}))
.subscribe()
},
open(e) {
this.navigate.next('../setTask/setTask')
}
})

其他具体优化期待各位读者在使用中体会~


一部由众多技术专家推荐, 帮你成为具有全面能力和全局视野工程师的进阶利器—— 《了不起的JavaScript工程师》出版了! 点击下方链接即刻踏上进阶之路!


亚里士朱德 wechat
更多WEB技术分享请订阅微信公众号“WEB学习社”