rxjs6 Multicasting Operators & Error Handling Operators

被刻印的时光 ゝ 提交于 2020-02-25 21:22:03

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));

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!