原文链接: rxjs6 Multicasting Operators & Error Handling Operators
上一篇: rxjs6 Filtering Operators
Multicasting Operators
multicast
多次订阅, 后订阅的数值依然是从头开始的
let s = interval(300)
s.subscribe(v => console.log('s1', v))
setTimeout(
() => s.subscribe(v => console.log('s2', v)),
1000
)
// s1 0
// s1 1
// s1 2
// s1 3
// s2 0
// s1 4
// s2 1
// s1 5
multicast 连接多个订阅对象, 使其即使不在同一时间订阅, 也能收到同样的值
let s = interval(300).pipe(multicast(() => new Subject()))
s.connect()
s.subscribe(v => console.log('s1', v))
setTimeout(
() => s.subscribe(v => console.log('s2', v)),
1000
)
// s1 0
// s1 1
// s1 2
// s1 3
// s2 3
// s1 4
// s2 4
// s1 5
publish
multicast 简写
let s = interval(300).pipe(publish())
s.connect()
s.subscribe(v => console.log('s1', v))
setTimeout(
() => s.subscribe(v => console.log('s2', v)),
1000
)
// s1 0
// s1 1
// s1 2
// s1 3
// s2 0
// s1 4
// s2 1
// s1 5
publishBehavior
有第一个默认值
let s = interval(300).pipe(publishBehavior('a'))
s.connect()
s.subscribe(v => console.log('s1', v))
setTimeout(
() => s.subscribe(v => console.log('s2', v)),
1000
)
// s1 a
// s1 0
// s1 1
// s1 2
// s2 2
publishLast
只取最后的数据
let s = interval(300).pipe(take(10), publishLast())
s.connect()
s.subscribe(v => console.log('s1', v))
setTimeout(
() => s.subscribe(v => console.log('s2', v)),
1000
)
// s1 9
// s2 9
publishReplay
指定缓存长度, 后面订阅时, 数据流从缓存中开始取
let s = interval(100).pipe(take(20), publishReplay(3))
s.connect()
s.subscribe(v => console.log('s1', v))
setTimeout(
() => s.subscribe(v => console.log('s2', v)),
1000
)
// s1 7
// s1 8
// s2 6
// s2 7
// s2 8
// s1 9
share
简写 share = publish + refCount
let s = interval(100).pipe(share())
s.subscribe(v => console.log('s1', v))
setTimeout(
() => s.subscribe(v => console.log('s2', v)),
1000
)
// s1 9
// s2 9
// s1 10
// s2 10
// s1 11
shareReplay
let s = interval(100).pipe(shareReplay(3))
s.subscribe(v => console.log('s1', v))
setTimeout(
() => s.subscribe(v => console.log('s2', v)),
1000
)
// s1 5
// s1 6
// s1 7
// s1 8
// s2 6
// s2 7
// s2 8
refCount
自动connect
let s = interval(100).pipe(publish(),refCount())
s.subscribe(v => console.log('s1', v))
setTimeout(
() => s.subscribe(v => console.log('s2', v)),
1000
)
// s1 8
// s1 9
// s2 9
// s1 10
// s2 10
// s1 11
Error Handling Operators
catchError
捕获流中的错误, 返回一个新的流, 在捕获函数中如果再次出现错误, 则会执行subscribe的异常捕获函数
range(1, 10).pipe(
map(v => {
if (v === 5)
throw 'err'
return v
}),
catchError(err => {
console.log('err', err)
return of('five')
})
).subscribe(
console.log,
err => console.log('err2', err),
() => console.log('complete')
)
// 1
// 2
// 3
// 4
// err err
// five
// complete
出错时, 从头执行
interval(100).pipe(
map(i => {
if (i === 10)
fs.readFileSync('./xxx')
return i
}),
catchError((err, caught) => caught),
)
.subscribe(x => console.log('sub', x))
// sub 0
// sub 1
// sub 2
// sub 0
// sub 1
// sub 2
// sub 0
// sub 1
// ...
retry
出错后重新尝试, 注意时间间隔
const {interval, defer, from} = require('rxjs')
const {repeat, tap, switchMap, take, retry} = require('rxjs/operators')
function ajax(text) {
return new Promise(
(resolve, reject) => {
setTimeout(
() => {
if (Math.random() < .5) {
console.log('reject', text)
reject('reject err')
return
}
console.log('resolve', text)
resolve('get ' + text)
}, 100 // 200 的时候 200*3 > 500, 不会停止
)
}
)
}
const input = interval(500)
// input 的输入间隔必须是input的三倍, 不然每当要停止的时候, input就会刷新, 重新开始请求
input.pipe(
tap(v => {
console.log('tap ', v)
}),
switchMap(x => defer(() => ajax(x)).pipe(
retry(2)
)),
).subscribe(val => {
console.log('val', val)
}, err => {
console.log('err', err)
})
// tap 0
// resolve 0
// val get 0
// tap 1
// reject 1
// resolve 1
// val get 1
// tap 2
// resolve 2
// val get 2
// tap 3
// reject 3
// resolve 3
// val get 3
// tap 4
// reject 4
// reject 4
// reject 4
// err reject err
retryWhen
外层数据流发生错误时, 在内层数据流发出数据的时候进行重试
const source = interval(1000);
const example = source.pipe(
map(val => {
if (val > 5) {
//error will be picked up by retryWhen
throw val;
}
return val;
}),
retryWhen(errors =>
errors.pipe(
//log error message
tap(val => console.log(`Value ${val} was too high!`)),
//restart in 6 seconds
delayWhen(val => timer(val * 1000))
)
)
);
/*
output:
0
1
2
3
4
5
"Value 6 was too high!"
--Wait 6 seconds then repeat
*/
const subscribe = example.subscribe(val => console.log(val));