簡體   English   中英

使用 RxJS 一次限制請求數

[英]Limit number of requests at a time with RxJS

假設我有 10 個 url,我希望為每個 url 發出一個 HTTP 請求。

我可以創建一個 URL 的可觀察對象,然后.flatMap()為每個 URL 的請求,然后.subscribe獲取結果。 但這會同時發出所有請求。

有沒有辦法將請求數量限制為固定數量,以免服務器超載

RxJS v6 更新

通過 mergeMap 管道,將並行限制作為第二個參數

const MAX_PARALLEL_QUERIES = 3;
let allResults = [];
let observables = [] // fill with observables
from(observables)
            .pipe(mergeMap(observable => observable, MAX_PARALLEL_QUERIES))
            .subscribe(
                partialResults => {
                    allResults = allResults.concat(partialResults);
                },
                err => {
                    // handle error
                },
                () => {
                    // get here when all obserable has returned
                    allResults.forEach(result=> {
                        // do what you want
                    });
                }
            );

現在是 2018 年,rxjs 5 來了,這就是我解決它的方法

urls$
  .mergeMap((url) => request({ url }), null, 10)
  .subscribe()

mergeMap (又名flatMap )已經將“最大並發性”作為其第三個參數(請參閱文檔

順便提一句。 我正在使用 universal-rxjs-ajax( request )來實現節點兼容性,但它應該與Observable.ajax一樣工作

這個問題在這里有答案: how-to-limit-the-concurrency-of-flatmap您也可以在此處查看答案並行觸發異步請求但使用 rxjs 按順序獲取結果

基本上它圍繞着使用merge(withMaxConcurrency)運算符。

我遇到了同樣的問題,現在找到了解決方案。 參考這個答案

如果你通過 fromNodeCallback 或 return Promise 創建 observable,它會創建一個熱 observable,並會在 flatMap 和訂閱后立即執行。 所以 flatMapWithMaxConcurrent 或 map&merge 沒有按預期工作。

 var start = Date.now() var now = ()=>Date.now()-start var test = Rx.Observable.fromNodeCallback(function(i, cb){ console.log(i, 'access', now()); setTimeout(function(){ cb(null, i) }, 1000); }) Rx.Observable.from([1,2,3]).flatMapWithMaxConcurrent(1, x=>test(x) ).subscribe(x=>console.log(x, 'finish', now())) /* output: 1 access 2 2 access 16 3 access 16 1 finish 1016 2 finish 1016 3 finish 1017 */
 <script src="http://www.cdnjs.net/ajax/libs/rxjs/4.1.0/rx.all.js"></script>

您需要將其轉換為冷可觀察對象,只需使用 Rx.Observable.defer。

 var start = Date.now() var now = ()=>Date.now()-start var test = Rx.Observable.fromNodeCallback(function(i, cb){ console.log(i, 'access', now()); setTimeout(function(){ cb(null, i) }, 1000); }) Rx.Observable.from([1,2,3]).flatMapWithMaxConcurrent(1, x=>Rx.Observable.defer( ()=>test(x)) ) //.map(x=>Rx.Observable.defer( ()=>test(x)) ).merge(1) // this works too.subscribe(x=>console.log(x, 'finish', now())) /* output: 1 access 3 1 finish 1004 2 access 1005 2 finish 2005 3 access 2006 3 finish 3006 */
 <script src="http://www.cdnjs.net/ajax/libs/rxjs/4.1.0/rx.all.js"></script>

這里只是一個旁注:在 RxJS v5 中, fromCallback()fromNodeCallback()分別更改為bindCallback()bindNodeCallback() 進一步閱讀鏈接: bindNodeCallback

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM