Reactive - 07 - Request

翻譯自:https://tech.io/playgrounds/929/reactive-programming-with-reactor-3/Request

Request


Description


Remember this diagram?

01_PublisherSubscriber.png

There's one aspect to it that we didn't cover: the volume control. In Reactive
Streams terms this is called backpressure. It is a feedback mechanism that
allows a Subscriber to signal to its Publisher how much data it is prepared
to process, limiting the rate at which the Publisher produces data.

有一個(gè)方面我們沒有涉及:容量控制。在反應(yīng)流術(shù)語中,這稱為backpressure(背壓)。這是一種反饋機(jī)制,
允許訂閱者向其發(fā)布者發(fā)出信號,告知其準(zhǔn)備處理多少數(shù)據(jù),從而限制發(fā)布者生成數(shù)據(jù)的速率。

This control of the demand is done at the Subscription level: a Subscription is
created for each subscribe() call and it can be manipulated to either cancel()
the flow of data or tune demand with request(long).

這種對需求的控制是在訂閱級別上完成的:為每個(gè)subscribe()調(diào)用創(chuàng)建一個(gè)訂閱,可以對其進(jìn)行操作,
以cancel()數(shù)據(jù)流或使用request(long)調(diào)整需求。

Making a request(Long.MAX_VALUE) means an unbounded demand, so the
Publisher will emit data at its fastest pace.

request(Long.MAX_VALUE)意味著無限的需求,因此發(fā)布者將以最快的速度發(fā)布數(shù)據(jù)。

Practice


The demand can be tuned in the StepVerifier as well, by using the relevant
parameter to create and withVirtualTime for the initial request, then
chaining in thenRequest(long) in your expectations for further requests.

也可以在StepVerifier中調(diào)整需求,通過使用相關(guān)參數(shù)來create和withVirtualTime 初始請求,
然后將thenRequest(long)鏈接到您對進(jìn)一步請求的期望中。

In this first example, create a StepVerifier that produces an initial
unbounded demand and verifies 4 values to be received, before completion.
This is equivalent to the way you've been using StepVerifier so far.

在第一個(gè)示例中,創(chuàng)建一個(gè)StepVerifier,生成初始無界需求,并在完成之前驗(yàn)證要接收的4個(gè)值。
這相當(dāng)于您目前使用StepVerifier的方式。
    // Create a StepVerifier that initially requests all values and expect 4 values to be received
    StepVerifier requestAllExpectFour(Flux<User> flux) {
        return StepVerifier
                .create(flux)
                .thenRequest(Long.MAX_VALUE)
                .expectNextCount(4)
                .expectComplete();
    }

Next we will request values one by one: for that you need an initial request,
but also a second single request after you've received and asserted the first element.

接下來,我們將逐個(gè)請求值:為此,您需要一個(gè)初始請求,但也需要在收到并斷言第一個(gè)元素后 做第二個(gè)單獨(dú)地請求。

Without more request, the source will never complete unless you cancel it.
This can be done instead of the terminal expectations by using .thenCancel().
If you want to also ensure no incoming signal is received over a Duration you
can instead use .expectTimeout(Duration).

如果沒有更多的請求,源將永遠(yuǎn)無法完成,除非您取消它。這可以通過使用.thenCancel()來代替終端期望。
如果您還想確保在一段時(shí)間內(nèi)沒有接收到任何傳入信號,則可以使用.expectTimeout(Duration)。
    // Create a StepVerifier that initially requests 1 value and expects User.SKYLER then requests another value and expects User.JESSE then stops verifying by cancelling the source
    StepVerifier requestOneExpectSkylerThenRequestOneExpectJesse(Flux<User> flux) {
        return StepVerifier
                .create(flux)
                .thenRequest(1).expectNext(User.SKYLER)
                .thenRequest(1).expectNext(User.JESSE)
                .thenCancel();
    }

A note on debugging


How to check that the previous sequence was requested one by one, and that a
cancellation happened?

如何檢查前一個(gè)序列是否被逐個(gè)請求,以及是否發(fā)生了取消?

It's important to be able to debug reactive APIs, so in the next example we will
make use of the log operator to know exactly what happens in terms of signals
and events.

能夠調(diào)試反應(yīng)式API很重要,因此在下一個(gè)示例中,我們將使用日志運(yùn)算符來準(zhǔn)確了解信號和事件的情況。

Use the repository to get a Flux of all users, then apply a log to it.
Observe in the console below how the underlying test requests it, and the other
events like subscribe, onNext...

使用repository獲取所有用戶的Flux,然后對其應(yīng)用日志。在下面的控制臺(tái)中觀察底層測試如何請求它,
以及其他事件,如subscribe、onNext等
    // Return a Flux with all users stored in the repository that prints automatically logs for all Reactive Streams signals
    Flux<User> fluxWithLog() {
        return repository.findAll().log();
    }

運(yùn)行日志如下:

2022-07-25 09:46:53 [main] INFO  reactor.Flux.Zip.1 - onSubscribe(FluxZip.ZipCoordinator)
2022-07-25 09:46:53 [main] INFO  reactor.Flux.Zip.1 - request(1)
2022-07-25 09:46:53 [parallel-1] INFO  reactor.Flux.Zip.1 - onNext(Person{username='swhite', firstname='Skyler', lastname='White'})
2022-07-25 09:46:53 [parallel-1] INFO  reactor.Flux.Zip.1 - request(1)
2022-07-25 09:46:54 [parallel-1] INFO  reactor.Flux.Zip.1 - onNext(Person{username='jpinkman', firstname='Jesse', lastname='Pinkman'})
2022-07-25 09:46:54 [parallel-1] INFO  reactor.Flux.Zip.1 - request(2)
2022-07-25 09:46:54 [parallel-1] INFO  reactor.Flux.Zip.1 - onNext(Person{username='wwhite', firstname='Walter', lastname='White'})
2022-07-25 09:46:54 [parallel-1] INFO  reactor.Flux.Zip.1 - onNext(Person{username='sgoodman', firstname='Saul', lastname='Goodman'})
2022-07-25 09:46:54 [parallel-1] INFO  reactor.Flux.Zip.1 - onComplete()

If you want to perform custom actions without really modifying the elements
in the sequence, you can use the "side effect" methods that start with do/doOn.

如果您想在不修改序列中元素的情況下執(zhí)行自定義操作,可以使用以do/doOn開頭的“副作用”方法。

For example, if you want to print "Requested" each time the operator receives
a request, use doOnRequest. If you want to print "Starting" first, upon
subscription before any signal has been received, use doFirst, etc.

例如,如果您想在運(yùn)算符每次收到請求時(shí)打印"Requested",請使用doOnRequest。
如果您想先打印"Starting",在收到任何信號之前訂閱時(shí),請使用doFirst等。

Each doOn method takes a relevant callback representing the custom action for
the corresponding event.

每個(gè)doOn方法接受一個(gè)相關(guān)回調(diào),表示相應(yīng)事件的自定義操作。

Note that you should not block or invoke operations with latency in these callbacks
(which is also true of other operator callbacks like map): it's more for quick
operations.

注意,您不應(yīng)該在這些回調(diào)中阻塞或調(diào)用具有延遲的操作(對于其他操作符回調(diào),如map也是如此):它更適合快速操作。
    // Return a Flux with all users stored in the repository that prints "Starring:" at first, "firstname lastname" for all values and "The end!" on complete
    Flux<User> fluxWithDoOnPrintln() {
        return repository
                .findAll()
                .doFirst(()->System.out.println("Starring:"))
                .doOnNext(user -> System.out.println(user.getFirstname()+" "+user.getLastname()))
                .doOnComplete(()->System.out.println("The end!"));
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,983評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內(nèi)容