小程序中使用rxjs,是真的舒服!
发布于 4 年前 作者 gang83 987 次浏览 来自 分享

rxjs-mp

在小程序中使用RxJs。(RxJs for miniprogram)

1. 安装依赖:

npm install --save rxjs-mp
npm install --save-dev rxjs
安装完成后使用小程序开发者工具构建npm,然后就可以在项目中使用rxjs了。此外,在vscode里还能享受rxjs的语法提示。

2. 如何使用:

为了演示在小程序中如何使用rxjs,现在举一个用rjxs封装http请求的例子。相对于Promise的封装,rxjs可随时取消已经发出的请求,这一点是Promise很难实现的。我们在utils目录下建一个http.js的文件。

2.1 封装utils/http.js

const Rx = require('rxjs-mp');

/**
 * Request 方法
 * @param {string} url 
 * @param {any} data 
 * @param {'GET'|'POST'|'PUT'|'DELETE'} method
 * @param {{header?: object}} options 
 */
function request(url, data = {}, method = "GET", { header }={}) {
  return new Rx.Observable(ob => {
    const requestTask = wx.request({
      url, data, method,
      header: {
        ...(header || {})
        Token: wx.getStorageSync('token')
      },
      success: res => {
        if (res.statusCode == 200) {
          ob.next(res);
          ob.complete();
        } else {
          ob.error(res);
        }
      },
      fail: err => {
        console.error(err);
        ob.error(err);
      }
    });
    return () => requestTask.abort();
  });
}

/**
 * GET 方法
 * @param {string} url 
 * @param {{header?: object}} options 
 */
function get(url, options) {
  return request(url, null, 'GET', options);
}

/**
 * POST 方法
 * @param {string} url 
 * @param {any} data 
 * @param {{header?: object}} options 
 */
function post(url, data, options) {
  return request(url, data, 'POST', options);
}

/**
 * PUT 方法
 * @param {string} url 
 * @param {any} data 
 * @param {{header?: object}} options 
 */
function put(url, data, options) {
  return request(url, data, 'PUT', options);
}

/**
 * GET 方法
 * @param {string} url 
 * @param {{header?: object}} options 
 */
function delete_(url, options) {
  return request(url, null, 'DELETE', options);
}

module.exports = {
  http: { get, post, put, delete: delete_, request }
}

2.2 调用封装,pages/your/page.js

管理rxjs订阅可以使用subsink2订阅管理工具(安装:npm install subsink2).

const Rx = require('rxjs-mp');
const { SubSink } = require('subsink2');
const http = require('../uitls/http.js');

const subs = new SubSink();

Page({
  data: {
    todoList: [],
  },
  onLoad() {
    // 发起请求
    this.httpRequest01();
    this.httpRequest02();
    this.httpRequest03();
  },
  httpRequest01() {
    // 请求1,用subsink的id方法标识请求,可以防重得请求,还可以随时取消
    subs.id('sub01').sink = http.get('htts://some-api-url').pipe(
      Rx.operators.map(res => res && res.data || {})
    ).subscribe(res => {
      console.log(res);
    }, err => {
      console.error(err);
    });
  },
  httpRequest02() {
    // 请求2,直接把请求加入订阅池
    subs.sink = http.post('htts://some-api-url', {}).pipe(
      Rx.operators.map(res => res && res.data || {})
    ).subscribe(res => {
      console.log(res);
    }, err => {
      console.error(err);
    });
  },
  httpRequest03() {
    // 请求2,把请求加入订阅池的另一种方法
    subs.add(http.get('htts://some-api-url').pipe(
      Rx.operators.map(res => res && res.data || {})
    ).subscribe(res => {
      console.log(res);
    }, err => {
      console.error(err);
    }));
  },
  bindUnSubRequest01() {
    // 取消request01的请求
    subs.id('sub01').unsubscribe();
  },
  onUnload() {
    // 销毁时,取消所有请求
    subs.unsubscribe();
  },
});

2.3 你还可使用rxjs其它强大的功能

比如消息发布和订阅,rxjs基于流的响应式编程帮你逃出Promise的回调地狱。

// ================================================
// utils/message.js
// ================================================
const Rx = require('rxjs-mp');

module.exports = {
   onSomeThingChange$: new Rx.Subject(),
   onOtherThingChange$: new Rx.BehaviorSubject(false),
}

// ================================================
// pages/your/page.js
// ================================================
const Rx = require('rxjs-mp');

const {
  onSomeThingChange$,
  onOtherThingChange$
} = require('../../utils/message.js');

onSomeThingChange$.pipe(
  Rx.operators.first()
).subscribe(status=> {
  console.log(status)
  // doSomeThing
});

onOtherThingChange$.subscribe(status => {
  console.log(status)
  // doSomeThing
});

onSomeThingChange$.next(true);
onOtherThingChange$.next(true);
回到顶部