Rxjs入门教程

该系列教程建立在有一定promise知识的前端同学身上,因为比较抽象,我们在例子中论证说明。
eg1.

var button = document.querySelector('button');
button.addEventListener('click', () => console.log('Clicked!'));

Using RxJS you create an observable instead.

var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
  .subscribe(() => console.log('Clicked!'));

关键字 Observable subscribe 有点像观察者模式

eg2

var count = 0;
var button = document.querySelector('button');
button.addEventListener('click', () => console.log(`Clicked ${++count} times`));

var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
  .scan(count => count + 1, 0)  //可以把0改成2 表示从2开始加
  .subscribe(count => console.log(`Clicked ${count} times`));
//scan 观察一个变量从0开始  有点像reduce  上一次的返回是这一次的输入

这里我们加入了一个scan 响应点击事件 更新数据

eg3

var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
  .throttleTime(1000)
  .scan(count => count + 1, 0)
  .subscribe(count => console.log(`Clicked ${count} times`));

throttleTime(1000) 函数截流,不懂自行google,表示1s内点击无效
是不是也比太难,但是也觉得还没过瘾,咱们接着看。。。

eg4

var count = 0;
var rate = 1000;
var lastClick = Date.now() - rate;
var button = document.querySelector('button');
button.addEventListener('click', (event) => {
  if (Date.now() - lastClick >= rate) {
    count += event.clientX;
    console.log(count)
    lastClick = Date.now();
  }
});
//这段代码想干嘛   叠加每次鼠标点击的clientX值嘛  不懂clientX自行google
var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
  .throttleTime(1000)
  .map(event => event.clientX)
  .scan((count, clientX) => count + clientX, 0)
  .subscribe(count => console.log(count));

下面这段代码很精神 ,注意每回点击的event.ClientX 传给了scan函数里面的clientX
你可以写成.map(event => event.clientY)试试 不影响scan里面的clientX

经过上面的例子大概也看出一下端倪来了,下面就来介绍observable可观察对象
eg1

var observable = Rx.Observable.create(function (observer) {
        observer.next(1);
        observer.next(2);
        observer.next(3);
        setTimeout(() => {
            observer.next(4);
            observer.complete();
        }, 1000);
    });

    console.log('just before subscribe');
    observable.subscribe({
        next: x => console.log('got value ' + x),
        error: err => console.error('something wrong occurred: ' + err),
        complete: () => console.log('done'),
    });
    console.log('just after subscribe');

//尝试下面这个写法你就知道了
var foo = Rx.Observable.create(function (observer) {
  console.log('Hello');
  observer.next(42); observer.next(41);console.log('Hellos');observer.next(49)
});

foo.subscribe(function (x) {
  console.log(x);
});

这里输出什么我就不写了,大家自己动手试一下,注意异步的问题。

我们来练习一下

1.每秒向观察者发射一个字符串"hi"的可观察对象。
var observable = Rx.Observable.create(function subscribe(observer) {
  var id = setInterval(() => {
    observer.next('hi')
  }, 1000);
});
2.订阅可观察对象
observable.subscribe(x => console.log(x));

哇 是不是很简单

注意下面这段代码

var observable = Rx.Observable.create(function subscribe(observer) {
observer.next(1);
observer.next(2);
observer.next(3);
observer.complete();
observer.next(4); // Is not delivered because it would violate the contract
});
// observer.complete(); 在前  4不会被输出

eg2

var observable = Rx.Observable.from([10, 20, 30]);
相当于
var observable = Rx.Observable.create(function subscribe(observer) {
observer.next(1);
observer.next(2);
observer.next(3);
}
// 大家可以动手尝试
observable可以调用unsubscribe 方法  结束观察

var observable = Rx.Observable.create(function subscribe(observer) {
// Keep track of the interval resource
var intervalID = setInterval(() => {
observer.next('hi');
}, 1000);

return function unsubscribe() {
//这个方法实际上是重写   就是说这个return写不写都一样,后面都可以调用unsubscribe
console.log('价格打印')
clearInterval(intervalID);
};
});

var subscription = observable.subscribe(x => console.log(x));
subscription.unsubscribe();
//

咱们用原声的写一个

function subscribe(observer) {
var intervalID = setInterval(() => {
observer.next('hi');
}, 1000);

return function unsubscribe() {
clearInterval(intervalID);
};
}

var unsubscribe = subscribe({next: (x) => console.log(x)});
unsubscribe(); // dispose the resources

是不是觉得也没什么难的,当然这只是开始,在angular4 http中会经常用到
接下来咱们看点有趣的

var observable1 = Rx.Observable.interval(400);
var observable2 = Rx.Observable.interval(300);

var subscription = observable1.subscribe(x => console.log('first: ' + x));
var childSubscription = observable2.subscribe(x => console.log('second: ' + x));

subscription.add(childSubscription);

setTimeout(() => {
  // Unsubscribes BOTH subscription and childSubscription
  subscription.unsubscribe();
}, 1000);

second: 0
first: 0
second: 1
first: 1
second: 2

大家到控制台去打印一下,这种操作是把2个observable叠加在一起,注意顺序问题,这里是subscription在前面,所以要用他去unsubscribe

其实现在已经算完全入门了Rxjs了,最后再看一个subject吧
eg1

var subject = new Rx.Subject();

subject.subscribe({
  next: (v) => console.log('observerA: ' + v)
});
subject.subscribe({
  next: (v) => console.log('observerB: ' + v)
});

subject.next(1);
subject.next(2);
output:
  observerA: 1
  observerB: 1
  observerA: 2
  observerB: 2

这是个什么意思,这回是先subscribe(订阅),但是没反应,直到后面用了.next()才有输出。
每一个Subject都是一个observable可观察对象,给定一个Subject后,你可以订阅它,提供的观察者将会正常的开始接收值。

eg2

var subject = new Rx.Subject();

subject.subscribe({
  next: (v) => console.log('observerA: ' + v)
});
subject.subscribe({
  next: (v) => console.log('observerB: ' + v)
});
var observable = Rx.Observable.from([1, 2, 3]);
observable.subscribe(subject); 

observerA: 1
observerB: 1
observerA: 2
observerB: 2
observerA: 3
observerB: 3

这里和前面不一样的就是所有订阅的都一起打印

下面有一个综合性的例子,其实也不太难哟
eg3

var source = Rx.Observable.interval(500);
var subject = new Rx.Subject();
var refCounted = source.multicast(subject).refCount();
var subscription1,subscription2,subscriptionConnect;

console.log('observerA subscribed');
subscription1 = refCounted.subscribe({
  next: (v) => console.log('observerA: ' + v)
});

setTimeout(() => {
  console.log('observerB subscribed');
  subscription2 = refCounted.subscribe({
    next: (v) => console.log('observerB: ' + v)
  });
}, 600);

//这里解除了subscription1 时间是1200  前面的interval是500  所以‘observerA’会被输出2次
setTimeout(() => {
  console.log('observerA unsubscribed');
  subscription1.unsubscribe();
}, 1200);

// 2s后 subscription2.unsubscribe()  所有的interval都停止了
setTimeout(() => {
  console.log('observerB unsubscribed');
  subscription2.unsubscribe();
}, 2000);

observerA subscribed
observerA: 0
observerB subscribed
observerA: 1
observerB: 1
observerA unsubscribed
observerB: 2
observerB unsubscribed

这个稍微有点复杂,有条件的同学可以再看一下

最后一个例子

var subject = new Rx.BehaviorSubject(0); // 0 is the initial value

subject.subscribe({
  next: (v) => console.log('observerA: ' + v)
});

subject.next(1);
subject.next(2);subject.next(3);

subject.subscribe({
  next: (v) => console.log('observerB: ' + v)
});

subject.next(4);
VM430:4 observerA: 0
VM430:4 observerA: 1
VM430:4 observerA: 2
VM430:4 observerA: 3
VM430:11 observerB: 3
VM430:4 observerA: 4
VM430:11 observerB: 4

new Rx.BehaviorSubject(0); 很关键,所以一开始就是0
注意一点是 observerB 会输出距他上面最近的一个next值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容