Rxjs初识(七)
*ngFor 使用trackBy 提高性能
<div *ngFor="let item of items;trackBy:trackByIndex">{{item.name}}</div>
items: Array<any> = [{name: 'Tom'}, {name: 'Jerry'}, {name: 'Mac'}, {name: 'John'}];
trackByIndex(index, item) {
return item.index
}
类似vue :key
RXjs
每秒发送值,取前两个
interval(1000).pipe(take(2)).subscribe(val=>{
console.log(val);
})
0
1
1s发一个值每4s发一次
timer(1000,4000).subscribe(val=>{
console.log(val);
})
延迟5s执行
of(1).pipe(delay(5000)).subscribe(val=>{
console.log(val);
})
1到10递增
range(1,10).subscribe(val=>{
console.log(val);
})
concat
let one = of(1, 2, 3);
let two = of(4, 5, 6);
one.pipe(concat(two)).subscribe(val => {
console.log(val);
})
// 延迟1s执行 1,'成功'
of(1).pipe(
delay(1000),
concat(from(new Promise(res=>res('成功'))))
).subscribe(val=>{
console.log(val);
})
Rxjs运行方式
// 创建可观察Observable物件
let a = interval(500).pipe(take(4));
// 建立观察者
let b = a.subscribe(val => {
console.log(val);
});
// 取消观察者
setTimeout(() => {
b.unsubscribe();
}, 1000)
第二种方式
let b = a.subscribe({
next(x) {
console.log(x);
}});
运算子删选信息
let a = fromEvent(document.querySelector('#ccc'), 'click');
let b = a.pipe(filter(x => {
return x.clientX < 500;
}));
b.subscribe(console.log)
Subject
// 建立主体物件(Subject)
let subject=new Subject();
// 创建可观察者
let clicks=fromEvent(document,'click')
// 处理操作
clicks.pipe(take(2))
// 把clicks全部交由subject主体进行广播
clicks.subscribe(subject)
// 最后订阅观察者
let subs1=subject.subscribe(x=>console.log(x.clientX))
let subs2=subject.subscribe(x=>console.log(x.clientX))
// 取消订阅
subs1.unsubscribe()
repeat 重复几次
of('xxx').pipe(repeat(3)).subscribe(val=>{
console.log(val);
})
xxx
xxx
xxx
请求json从app的目录开始
this.http.get<any>('/assets/rxjsget.json').subscribe(val => {
console.log(val);
})
一段时间内触发一次 audit
const clicks = fromEvent(document, 'click');
const result = clicks.pipe(audit(ev => interval(1000)));
result.subscribe(x => console.log(x));
每秒最多点击1次
const clicks = fromEvent(document, 'click');
const result = clicks.pipe(auditTime(1000));
result.subscribe(x => console.log(x));
buffer 观察缓冲区
每次点击时,发出最近间隔事件的数组
let a = fromEvent(document.querySelector('#ccc'), 'click');
interval(1000).pipe(buffer(a)).subscribe(val=>{
console.log(val);
})
bufferCount 缓冲次数
第一个参数是 数组的长度
第二个参数是 前一次的索引
interval(1000).pipe(bufferCount(3,2)).subscribe(val=>{
console.log(val);
})
[0, 1, 2]
[2, 3, 4]
[4, 5, 6]
[6, 7, 8]
buffterTime 特定时间段内缓冲
每秒发出最近的事件
const clicks = fromEvent(document, 'click');
const buffered = clicks.pipe(bufferTime(1000));
buffered.subscribe(x => console.log(x));
2秒钟发出一次,每5秒钟执行一次
const clicks = fromEvent(document, 'click');
const buffered = clicks.pipe(bufferTime(2000, 5000));
buffered.subscribe(x => console.log(x));
count 次数
计算1到10的奇数次数
range(1,10).pipe(count(v=>v%2==1)).subscribe(val=>{ console.log(val); })
max()
of(1,10,2,5,6).pipe(max()).subscribe(val=>{
console.log(val);
})
interface Person {
name: string,
age: number
}
of<Person>(
{age: 7, name: 'Foo'},
{age: 15, name: 'Bar'},
{age: 9, name: 'Beer'},
).pipe(max<Person>((a: Person, b: Person) => a.age - b.age)).subscribe(val => {
console.log(val); // {age: 15, name: "Bar"}
})
min()
of<Person>(
{age: 7, name: 'Foo'},
{age: 15, name: 'Bar'},
{age: 9, name: 'Beer'},
).pipe(min<Person>((a: Person, b: Person) => a.age - b.age)).subscribe(val => {
console.log(val);
})
debounce
一段点击后发出最近的点击
const clicks = fromEvent(document, 'click');
const result = clicks.pipe(debounce(() => interval(1000)));
result.subscribe(x => console.log(x));
bebounceTime
跟bebounce 一样,只不过一个是函数,一个是字段
const clicks = fromEvent(document, 'click');
const result = clicks.pipe(debounceTime(1000));
result.subscribe(x => console.log(x));
defaultIfEmpty()
5秒內没点击
const clicks = fromEvent(document.querySelector('#ccc'), 'click');
const clicksBeforeFive = clicks.pipe(takeUntil(interval(5000)));
let result: Observable<any> = clicksBeforeFive.pipe(defaultIfEmpty('no clicks'));
result.subscribe(x => console.log(x));
distinct 去重
of(1, 1, 2, 2, 2, 1, 2, 3, 4, 3, 2, 1).pipe(
distinct(),
)
.subscribe(x => console.log(x)); // 1, 2, 3, 4
interface Person {
age: number,
name: string
}
of<Person>(
{age: 4, name: 'Foo'},
{age: 7, name: 'Bar'},
{age: 5, name: 'Foo'},
).pipe(
distinct((v: Person) => v.name)
).subscribe(val=>{
console.log(val);
})
elementAt
仅发出第三次点击事件
const clicks = fromEvent(document.querySelector('#ccc'), 'click'); clicks.pipe(elementAt(2)).subscribe(console.log)
startWith
of('aaaa').pipe( startWith('bbb','cccc') ).subscribe(val=>{ console.log(val); }) 'bbb' 'cccc' 'aaaa'
endWith
附加一次发射
of(1,2,3).pipe( endWith(4) // endWith(4,5,6,7) ).subscribe(val=>{ console.log(val); }) 1 2 3 4
every
of(1,2,3,4).pipe(every(val=>val>5)).subscribe(va=>{
console.log(va);// false
})
mapTo 给定一个常量
const clicks = fromEvent(document.querySelector('#ccc'), 'click');
clicks.pipe(
mapTo('hi')
).subscribe(val=>{
console.log(val);
})
expand 递归将每个源值投影到一个observable
每次点击2的幂,最多10次
const clicks = fromEvent(document.querySelector('#ccc'), 'click'); clicks.pipe( mapTo(1), expand(x => of(2 * x).pipe(delay(1000))), take(10), ).subscribe(x=>{ console.log(x); })
filter
of(1,2,3,4,5).pipe(
filter(v=>v>3)
).subscribe(val=>{
console.log(val);
})
4
5
find
of(1, 2, 3, 4, 5).pipe(find(val => val > 3)).subscribe(val => {
console.log(val);
})
4
findIndex
first()
of(1, 2, 3, 4, 5).pipe(first()).subscribe(val => {
console.log(val);
})
1
仅返回第一次点击
const clicks = fromEvent(document.querySelector('#ccc'), 'click');
clicks.pipe(first()).subscribe(val=>{
console.log(val);
})
first(ev => ev.target.tagName === 'DIV')
last()
isEmpty
如果输入observable发出任何值,则为false;如果输入observable完成而不发出任何值,则为true
of().pipe(isEmpty()).subscribe(val=>{
console.log(val); //true
})
map
每次点击映射到点击的clientX位置
const clicks = fromEvent(document.querySelector('#ccc'), 'click'); clicks.pipe(map((ev) => ev.clientX)).subscribe(val => { console.log(val); })
mergeScan
累加器,返回一个源
计算点击事件的数量
const clicks = fromEvent(document.querySelector('#ccc'), 'click'); clicks.pipe(mapTo(1)).pipe( mergeScan((acc, val) => of(acc + val), 0) ).subscribe(val => { console.log(val); })
pluck 映射到指定的嵌套属性
每次点击映射到点击的目标元素的tagName
const clicks = fromEvent(document, 'click');
const tagNames = clicks.pipe(pluck('target', 'tagName'));
tagNames.subscribe(x => console.log(x));
reduce
累加器
range(1,10).pipe(
reduce((acc,val)=>acc+val,0)
).subscribe(val=>{
console.log(val);
})
repeatWhen
重复点击消息流
const clicks = fromEvent(document.querySelector('#ccc'), 'click'); of('messages ').pipe(repeatWhen(()=>clicks)).subscribe(val=>{ console.log(val); })
skip
跳跃前几项
of(1,2,3,4,5).pipe( skip(3) ).subscribe(val=>{ console.log(val); }) 4 5
skipLast
返回前几项
range(1,5).pipe(skipLast(2)).subscribe(val=>{ console.log(val); }) 1 2 3
switchAll
对于每次新点击,取消前一个间隔并订阅新间隔
let clicks = fromEvent(document.querySelector('#ccc'), 'click');
clicks.pipe(map(v => interval(1000))).pipe(
switchAll()
).subscribe(val => {
console.log(val);
})
take
执行几次
interval(1000).pipe(take(4)).subscribe(val=>{
console.log(val);
})
0
1
2
3
takeLast
返回最后几次
range(1,10).pipe(takeLast(3)).subscribe(val=>{
console.log(val);
})
返回最后3次
8
9
10
takeUntil
点击的时候停止
每秒打一次,点击的时候停止 let clicks = fromEvent(document.querySelector('#ccc'), 'click'); interval(1000).pipe(takeUntil(clicks)).subscribe(val=>{ console.log(val); })
takeWhile
clientX属性大于200 时发生点击事件
let clicks = fromEvent(document.querySelector('#ccc'), 'click');
const result = clicks.pipe(takeWhile(ev => ev.clientX > 200));
result.subscribe(x => console.log(x));
throttle
节流操作
let clicks = fromEvent(document.querySelector('#ccc'), 'click'); clicks.pipe(throttle(e=>interval(3000))).subscribe(val=>{ console.log(val); })
throttleTime
跟上面一样
throttleTime(1000)
timestamp
点击的返回事件附加时间戳
let clicks = fromEvent(document.querySelector('#ccc'), 'click');
clicks.pipe(timestamp()).subscribe(val=>{
console.log(val);
})
toArray()
interval(1000).pipe(
take(5),
toArray()
).subscribe(val=>{
console.log(val);
})
[0, 1, 2, 3, 4]
windowTime
每两秒中,最多发出两次点击
let clicks = fromEvent(document.querySelector('#ccc'), 'click');
clicks.pipe(
windowTime(2000),
map(win=>win.pipe(take(2))),
mergeAll()
).subscribe(val=>{
console.log(val);
})
withLatestFrom()
每个click事件上,发出带有最新计时器时间和click事件的数组
let clicks = fromEvent(document.querySelector('#ccc'), 'click');
clicks.pipe(withLatestFrom(interval(1000))).subscribe(val=>{
console.log(val);
})
defer
创建一个observable,在订阅时,给每个新的Observer创建Observable
defer(()=>of(1,2,3)).subscribe(val=>{ console.log(val); });
forkJoin
组合起来发送值
forkJoin([ of(1,2,3,4), from([1,2,3]), Promise.resolve(12), Promise.resolve(8) ]).subscribe(val=>{ console.log(val); }) [4, 3, 12, 8] forkJoin({ name:'xxx', age:from([1,2,3]), bar:Promise.resolve(10) }).subscribe(val=>{ console.log(val); }) {name: "x", age: 3, bar: 10}
from
from([1,2,3]).subscribe(val=>{
console.log(val);
})
1
2
3
fromEventPattern
DOM文档上的点击
function addClickHandler(handler) {
document.addEventListener('click', handler);
}
function removeClickHandler(handler) {
document.removeEventListener('click', handler);
}
const clicks = fromEventPattern(
addClickHandler,
removeClickHandler
);
clicks.subscribe(x => console.log(x));
Generate
参数:
初始值,条件,重复,最后一个应该是每次值得修饰
for循环 const source = generate(0, x => x < 5, x => x + 1); source.subscribe(val => { console.log(val); }) 最后一个值修饰 const source = generate(0, x => x < 5, x => x + 1,x=>x+'!!!'); source.subscribe(val => { console.log(val); }) 0!!! 1!!! 2!!! 3!!! 4!!!
iif
iif(
() => true,
of('true'),
of('false')
).subscribe(val => {
console.log(val);
})
// true
iif(
() => false,
of('true'),
of('false')
).subscribe(val => {
console.log(val);
})
// false
pairs
把对象转成[key,value]成对的Observable
pairs({name:'xxx',age:'xx'}).pipe(toArray()).subscribe(val=>{ console.log(val); }) [['name','xxx'],['age','xx']]
partition
将源Observable分为两个,一个具有满足谓词的值,另一个具有不满足谓词的值。
const [event$, odds$] = partition(of(1, 2, 3, 4, 5), (value, index) => value % 2 == 0); event$.subscribe(val => { console.log(val); }); odds$.subscribe(val => { console.log(val); })
race
返回最早订阅的
const obs1 = interval(1000).pipe(mapTo('fast one'));
const obs2 = interval(3000).pipe(mapTo('medium one'));
const obs3 = interval(5000).pipe(mapTo('slow one'));
race(obs3, obs1, obs2)
.subscribe(
winner => console.log(winner)
);
'fast one'
timer
5s后返回值
timer(5000).pipe(mapTo('我')).subscribe(val=>{
console.log(val);
})
5s返回第一个值,后面每1s返回一个值
timer(5000,1000).pipe(mapTo('我')).subscribe(val=>{
console.log(val);
})
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬