携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
组合类操作符
combineLatest
组合多个 Observables 来创建一个 Observable ,该 Observable 的值根据每个输入 Observable 的最新值计算得出的。
const { skip,Observable,concatMap, fromEvent, fromPromise, interval, take, from, range, of, map, filter,scan, buffer, Subject, pluck, switchMap, debounceTime, throttleTime, distinct, mergeMap, isEmpty, empty, EMPTY, combineLatest } = require('rxjs');
const source1$ = interval(2000).pipe(take(3));
const source2$ = interval(1000).pipe(take(5));
combineLatest([source1$, source2$]).pipe(map(([s1, s2]) => {
return `${s1}-${s2},`;
})).subscribe((x) => {
console.log(x);
});
console.log('End');
End
0-0,
0-1,
0-2,
1-2,
1-3,
1-4,
2-4,
zip
zip操作符是将多个Observable打了个包,第一个Observable中的第一个数据,对应于第二个Observable中第一个数据,第二个数据对应第二个,完全一一对应的,获得的数据是一个数组。日常工作中使用的很多。
const source1$ = interval(2000).pipe(take(3));
const source2$ = interval(1000).pipe(take(5));
zip(source1$, source2$).pipe(map(([s1, s2]) => {
return `${s1}-${s2},`;
})).subscribe((x) => {
console.log(x);
});
console.log('End');
End
0-0,
1-1,
2-2,
const age$ = of(27, 25, 29);
const name$ = of('Foo', 'Bar', 'Beer');
const isDev$ = of(true, true, false);
zip(age$, name$, isDev$).pipe(
map(([age, name, isDev]) => ({ age, name, isDev }))
)
.subscribe(x => console.log(x));
多播类操作符
publish
返回 ConnectableObservable,它是 Observable 的变种,它会一直等待,直到 connnect 方法被调用才会开始把值发送给那些订阅它的观察者。
publish将在V8中彻底废除,可以采用新写法。
const source$ = new Observable((observer) => {
observer.next(2);
observer.next(13);
observer.complete();
});
// const sourceNew$ = source$.pipe(publish());
const sourceNew$ = connectable(source$);
sourceNew$.subscribe((x) => {
console.log(x);
});
sourceNew$.connect();
console.log('End');
错误处理操作符
catchError
catchError可以优雅地处理observable中的错误,catchError函数中一定要返回一个observable。
const source$ = new Observable((observer) => {
observer.next(2);
observer.next(13);
throw new Error();
observer.complete();
});
source$.pipe(catchError((err, caught) => {
return of('出错了');
})).subscribe((x) => {
console.log(x);
});
console.log('End');
2
13
出错了
End
retry
如果发生错误,以指定次数重试 observable 序列。
const source = interval(1000).pipe(take(20));
const example = source.pipe(
mergeMap(val => {
// 抛出错误以进行演示
if (val > 5) {
return throwError('Error!');
}
return of(val);
}),
// 出错的话可以重试2次
retry(2)
).subscribe((x) => {
console.log(x);
});
console.log('End');
// 重试两次后结束
工具类操作符
tap
透明地执行操作或副作用,比如打印日志。之前tap操作符叫do。
const source = of(1, 2, 3, 4, 5);
// 使用 tap 透明地打印 source 中的值
const example = source.pipe(
tap(val => console.log(`BEFORE MAP: ${val}`)),
map(val => val + 10),
tap(val => console.log(`AFTER MAP: ${val}`))
);
// 'tap' 并不转换值
// 输出: 11...12...13...14...15
const subscribe = example.subscribe(val => console.log(val));
console.log('End');
BEFORE MAP: 1
AFTER MAP: 11
11
BEFORE MAP: 2
AFTER MAP: 12
12
BEFORE MAP: 3
AFTER MAP: 13
13
BEFORE MAP: 4
AFTER MAP: 14
14
BEFORE MAP: 5
AFTER MAP: 15
15
End
条件和布尔操作符
every
如果完成时所有的值都能通过断言,那么发出 true,否则发出 false 。
// 发出5个值
const source = of(1, 2, 3, 4, 5);
const example = source.pipe(
// 每个值都是偶数吗?
every(val => val % 2 === 0)
);
// 输出: false
const subscribe = example.subscribe(val => console.log(val));
console.log('End');
false
End
数学和聚合操作符
count
Counts the number of emissions on the source and emits that number when the source completes.
const numbers = range(1, 7);
const result = numbers.pipe(count(i => i % 2 === 1));
result.subscribe(x => console.log(x));
// Results in:
// 4
reduce
Applies an accumulator function over the source Observable, and returns the accumulated result when the source completes, given an optional seed value.
和数组的reduce方法类似。
const source$ = interval(1000).pipe(take(5));
source$.pipe(reduce((acc, cur) => (acc+cur))).subscribe((x) => {
console.log(x);
});
console.log('End');
// End
// 10
至此,所有关于操作符的介绍就结束了,操作符是Rxjs的精华,但是没有必要花费大量的精力去精通所有的操作符,先掌握常用的一些操作符就可以,在需要的时候可以再去官网查阅。