【问题标题】:RxJS: Throttle rate-limited API callsRxJS:限制速率限制的 API 调用
【发布时间】:2018-10-23 01:44:32
【问题描述】:

几天来,我一直在努力(和搜索)寻找解决方案,虽然以下工作有效,但我不禁觉得有一种更 rxjs-y 的方式来做这件事。

我有一组 URL 可以从具有速率限制的外部源下载,例如每分钟不超过 100 个调用。

const sources = ['a.jpg', 'b.jpg', 'c.jpg'];

timer(0, 1000).pipe(
  switchMap(index => of(sources[index])),
  takeWhile(_ => _ !== undefined),
  switchMap(url => {
    return from(download(url))
  })
).subscribe(
  next => console.log(next),
  err => console.error(err),
  () => console.info('Done')
)

// Pseudo
function download(url) {
  return new Promise((resolve, reject) => {
    resolve('Downloaded ' + url)
  })
}

似乎有点迂回和hacky。

遍历数组以免因每秒请求过多而被锁定的最佳方法是什么?

【问题讨论】:

    标签: javascript rxjs


    【解决方案1】:

    这取决于您何时想要延迟,但您可以使用例如保证 1 秒延迟:

    import { from, of, merge as mergeStatic, timer } from 'rxjs';
    import { delay, concatMap, merge, ignoreElements } from 'rxjs/operators';
    
    const sources = ['a.jpg', 'b.jpg', 'c.jpg'];
    const mockRequest = s => of(s)
    
    from(sources)
      .pipe(
        concatMap(url => mergeStatic(
          mockRequest(url),
          timer(1000).pipe(ignoreElements())
        ))
      )
      .subscribe(console.log)
    

    或者,如果您想在请求完成后进行延迟(该请求时间 + 延迟),您可以使用 mockRequest(url).pipe(delay(1000))

    如果你想先发出结果然后进行交易,你可以切换运算符的顺序:

    from(sources)
      .pipe(
        concatMap(url => mockRequest(url).pipe(
          merge(timer(1000).pipe(ignoreElements()))
        ))
      )
      .subscribe(console.log)
    

    现场演示:https://stackblitz.com/edit/rxjs6-demo-qwdfgp?file=index.ts

    【讨论】:

    • 完美。谢谢马丁!
    猜你喜欢
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多