rxjs6 Multicasting Operators & Error Handling Operators

原文链接: rxjs6 Multicasting Operators & Error Handling Operators

上一篇: rxjs6 Filtering Operators

下一篇: rxjs6 Utility 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));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值