小程序中使用rxjs,是真的舒服!
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);