RxWX又添新成员

666 阅读5分钟
原文链接: mp.weixin.qq.com

RxWX简介:RxWX是可以让你写出更高效更优雅微信小程序的开源项目,它主要完成了两项工作:将RxJS移植到小程序端和将wx原生API转化成Observable对象。项目地址:https://github.com/yalishizhude/RxWXnpm模块名: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函数来取消订阅,从而忽略请求返回的结果,不执行对应的操作。

// 原生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()

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

事件防抖

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

<!-- xwml代码 -->
<view bindtap="submit">submit</view>// js代码
submit() {
  // 处理逻辑....
  wx.navigateTo({
    url: 'xxx/yyy'
  })
}
//...

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

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

// js代码
submit() {
  rxwx.navigateTo({
    url: 'xxx/yyy'
  })
  .debounceTime(1000)  // 1000ms之内只触发一次
  .subscribe()
}

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

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

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手动调用即可实现。具体代码如下:

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')
  }
})

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

本文可被转发或分享,但必须保留完整图文信息和出处,作者保留追究一切法律责任的权利和手段~

搜索关注公众号“web学习社”~