专栏首页极乐技术社区用 RxJS、RxWX 编写微信小程序

用 RxJS、RxWX 编写微信小程序

RxJS

RxJS是微软推出的ReactiveX系列,符合纯函数特点的第三方开源库有非常著名underscore和lodash,以及更加强大的RxJS。它可以用来优雅地处理异步和事件。主要通过它的核心类型Observable,以及强大的操作符 (map、filter、reduce、every等,其中大部分都是纯函数)来实现。

官方给它最直白的定义是:可以把 RxJS 当做是用来处理事件的 Lodash 。

使用RxJS的代码消除了一些中间变量,使用操作符来分步执行逻辑,可读性更强、耦合性更低,更方便测试和修改。关于RxJS在web端和node.js服务端的应用都不乏文章,这一次突破常规,来讲一讲在微信小程序开发中的使用。

小程序

直接在小程序中使用RxJS是会报错的,所以我建立了一个开源项目来解决这个问题:RxWX(项目地址:https://github.com/yalishizhude/RxJS )。

封装了两个js文件。

  • Rx.js。对Rx.js进行了一些修改使其能在小程序中运行。
  • RxWX.js。基于Rx.js对微信的api进行了封装,调用同名API不再使用回调,而是返回Observalbe对象。

安装

提供两种安装途径

  • Github
  • git clone https://github.com/yalishizhude/RxWX.git

可以直接下载项目,将根目录的Rx.js和RxWX.js复制到小程序项目中,也可以访问该网址复制粘贴这两个文件内容。

npm npm i rxjs-wx 将node_modules/rxjs-wx目录下的Rx.js和RxWX.js复制到小程序项目中。

使用

小程序的API大多数都不是按照纯函数的思想设计的,把返回结果赋值给入参的success、fail、complete属性。

在逻辑简单复杂的情况下很容堕入“回调地狱”,而且同步和异步的接口调用方式也不一致。而使用RxJS就可以解决这些问题,下面来看几个例子。

处理回调

假设有这样一个需求,先通过 wx.getUserInfo 获取用户信息,然后传给后端服务获取该用户其它信息,显示在页面上。

// 普通代码let self = thiswx.getUserInfo({  success: (res) => {
    wx.request({      method: 'GET',      url: 'xxx/user',      data: res.userInfo,
      success(r) {
        self.setData({userInfo:r})
      },
      fail(e) {
        self.setData({userInfo:'not found'})
      }
    })
  },
  fail(e) {    console.error(e)
  }
})// 使用RxWXimport obs from './RxWX'obs.getUserInfo()
  .catch(e => console.error(e))
  .switchMap(({ userInfo }) => obs.request({ method: 'GET', url: 'xxx/user', data: user }))
  .subscribe(userInfo => self.setData({ userInfo: r }), e => self.setData({ userInfo: 'not found' }))

处理事件

曾经在开发小程序的时候使用navigator组件碰到一个比较严重的问题:快速多次点击的时候会发生多次页面跳转,跳转完成后需要多次点击“返回”才能退回到原页面。

为了解决这个问题,一般可以手动绑定事件,然后进行一个防抖操作。

// 普通代码let tapping = false...
tap(e) {  if(!tapping) {
    wx.navigateTo({ url: '../demo/demo' })
    tapping = true
    setTimeout(() => tapping=false, 1000)
  }
}// 使用RxWXimport obs from './RxWX'tap(e) {
  obs.navigateTo({ url: '../demo/demo' })
  .debounce(1000)
  .subscribe()
}

RxWX使用场景

微信小程序SDK版本:1.7.0 微信开发者工具版本:1.01

演示项目下载地址: https://github.com/yalishizhude/RxWX/tree/master/example

Get started 按照RxWX说明,把Rx.js和RxWX.js文件放入到utils目录下。 其中Rx.js是可运行在小程序中的Rx.js模块,RxWX.js是利用Rx.js对小程序API进行的封装,封装后API函数将返回Observable对象,属性值不变。 使用时必须引入该文件,比如import rxwx from '../../utils/RxWX.js'同步API与异步API

// 原写法
try {
  let result = wx.removeStorageSync('xx')
  console.log(result) 
} catch(e) {
  console.error('小程序API发现错误')
}
// 使用RxWX
import rxwx from '../../utils/RxWX.js'
rxwx.removeStorageSync('xx')
  .catch((e) => console.error('RxWX发现错误'))
  .subscribe((resp) => console.log(resp))

看上去好像没太大区别。别着急,接着我们来继续看看异步API的调用~

// 原写法
wx.removeStorage({
  key: 'xx',
  success: function(res) {
    console.log(res)
  },
  error: function(e) {
    console.error('小程序API发现错误')
  }
})
// 引用RxWX,rxwx具有wx的所有函数和值,但是调用函数返回的是Observable对象
import rxwx from '../../utils/RxWX.js'
rxwx.removeStorage({key: 'xx'})
  .catch((e) => console.error('RxWX发现错误'))
  .subscribe((resp) => console.log(resp)

在调用同步时RxWX没有太大优势,但在调用异步API的时候以流的方式来处理结果和异常,显然优于回调。而且代码内容和同步调用方式相比并无变化(只修改了函数名和入参)。

这种统一的操作方式可以让开发者更好的关注业务逻辑,而不需要去分辨API到底是异步还是同步,执行结果到底是在回调中获取还是返回值获取。

这种处理方式是不是让你想起点什么?欢迎留言讨论~

嵌套登录后获取用户信息

// 调用小程序原生API
wx.login({
  success(res) {
    wx.getUserInfo({
      success(res) {
        console.log(res.userInfo)
      },
      fail(e) {
        console.error(e)
      }
    })
  },
  fail(e) {
    console.error(e)
  }
})
// 调用RxWX
import rxwx from '../../utils/RxWX.js'
rxwx.login()
  .switchMap(() => rxwx.getUserInfo())
  .catch(e => console.error(e))
  .subscribe(res => console.log(res.userInfo))

原生写法很容易坠入回调地狱,而利用RxWx的代码直观易读。

合并 同时获取用户信息和系统信息后进行操作。

// 调用小程序API
let getUser =  new Promise((success, fail) => {
  wx.getUserInfo({
    success,
    fail
  })
})
let getSystem =  new Promise((success, fail) => {
  wx.getSystemInfo({
    success,
    fail
  })
})
Promise.all([getUser, getSystem])
.then((resp) => console.log(resp), e => console.error(e))
// 调用RxWX
import rxwx, {Rx} from '../../utils/RxWX.js'
Rx.Observable.zip(rxwx.getUserInfo(), rxwx.getSystemInfo())
  .catch(e => console.error(e))
  .subscribe(resp => console.log(resp)

其他

RxWX同时还支持wx对象的其它非函数属性,比如:

import obs from './RxWX'console.log(obs.version) 
// {info:"", updateTime:"2017.7.10 19:35:05", version:"1.4.0"}

最后

RxJS和RxWX是第三方库,也是进入纯函数世界的大门,更是一种编写更好代码的思维方式。

本文分享自微信公众号 - 极乐技术社区(wxapp-union),作者:爱技术乐分享

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-12-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一斤代码深入理解系列(七):微信小程序中使用微信风格样式库-WeUI

    WeUI 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一。包含button、cell、d...

    极乐君
  • 使用ES6新特性开发微信小程序(1)

    ECMAScript 6(简称ES6)是JavaScript语言的最新标准。因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015。 ...

    极乐君
  • 一斤代码深入理解系列(三):微信小程序和服务器通信

    如果你的小程序需要和远程的服务进行交互,比如访问你自己的或别人提供的远程API来操作数据(增删改查),那么你就需要一种和远程服务器进行通信的机制来...

    极乐君
  • 在Web.Config文件中使用configSource

    我们都知道,在asp.net中修改了配置文件web.config后,会导致应用程序重启,所有会话(session)丢失。然而,应用程序的配置信息放在配置文件里是...

    DougWang
  • WordPress如何关闭Feed功能?

    WordPress最为一个开源的blog系统,Feed功能不需要借助任何的工具就可以直接的生成,但是如果你的网站不需要此功能,那么feed就成为了一个摆设,那么...

    空木白博客
  • MySQL的查询优化(一)

    “ 在上一篇关系型数据库之MySQL的文章中,我们介绍了什么是关系型数据库以及MySQL查询优化的大体思路,那今天我们就针对具体的语句来看一下,如何优化MySQ...

    每天学Java
  • 加密学原理

    对称加密: 用一个key加密, 再用同一个key解密。 非对称加密:用一个public key加密, 再用一个secret key解密 非对称加密在现实世...

    lilugirl
  • 4.4 串操作应用举例

    1、文本编译程序是一个面向用户的系统服务程序,广泛用于源程序的输入和修改,甚至用于报刊和书籍的编辑排版以及办公室的公文书信的起草和润色。

    C语言入门到精通
  • 杨小杰站长之家工具箱1.2

    Youngxj
  • Linux强化论:15步打造一个安全的Linux服务器

    可能大多数人都觉得Linux是安全的吧?但我要告诉你,这种想法绝对是错误的!假设你的笔记本电脑在没有增强安全保护的情况下被盗了,小偷首先就会尝试用“root”(...

    释然

扫码关注云+社区

领取腾讯云代金券