1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      kotlin協(xié)程——&gt;select表達(dá)式(實驗性的)-創(chuàng)新互聯(lián)
      select 表達(dá)式(實驗性的)kotlin協(xié)程——>se
lect表達(dá)式(實驗性的)

      select 表達(dá)式可以同時等待多個掛起函數(shù),并 選擇 第?個可?的。

      創(chuàng)新互聯(lián)建站主要從事網(wǎng)站制作、成都網(wǎng)站制作、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)梓潼,十年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):028-86922220

      在通道中 select

      我們現(xiàn)在有兩個字符串?產(chǎn)者:fizz 和 buzz 。其中 fizz 每 300 毫秒?成?個“Fizz”字符串:

      fun CoroutineScope.fizz() = produce { while (true) { // 每 300 毫秒發(fā)送?個 "Fizz" delay(300) send("Fizz") } }

      接著 buzz 每 500 毫秒?成?個“Buzz!”字符串:

      fun CoroutineScope.buzz() = produce { while (true) { // 每 500 毫秒發(fā)送?個"Buzz!" delay(500) send("Buzz!") } }

      使? receive 掛起函數(shù),我們可以從兩個通道接收 其中?個 的數(shù)據(jù)。但是 select 表達(dá)式允許我們使? 其 onReceive ?句 同時 從兩者接收:

      suspend fun selectFizzBuzz(fizz: ReceiveChannel, buzz: ReceiveChannel) { select { // 意味著該 select 表達(dá)式不返回任何結(jié)果 fizz.onReceive { value -> // 這是第?個 select ?句 println("fizz -> '$value'") } buzz.onReceive { value -> // 這是第?個 select ?句 println("buzz -> '$value'") } } }

      讓我們運?代碼 7 次:

      val fizz = fizz() val buzz = buzz() repeat(7) { selectFizzBuzz(fizz, buzz) } coroutineContext.cancelChildren() // 取消 fizz 和 buzz 協(xié)程

      這段代碼的執(zhí)?結(jié)果如下:

      fizz -> 'Fizz' buzz -> 'Buzz!' fizz -> 'Fizz' fizz -> 'Fizz' buzz -> 'Buzz!' fizz -> 'Fizz' buzz -> 'Buzz!'

      通道關(guān)閉時 select

      select 中的 onReceive ?句在已經(jīng)關(guān)閉的通道執(zhí)?會發(fā)?失敗,并導(dǎo)致相應(yīng)的 select 拋出異常。我 們可以使? onReceiveOrNull ?句在關(guān)閉通道時執(zhí)?特定操作。以下?例還顯?了 select 是?個返 回其查詢?法結(jié)果的表達(dá)式:

      suspend fun selectAorB(a: ReceiveChannel, b: ReceiveChannel): String = select { a.onReceiveOrNull { value -> if (value == null) "Channel 'a' is closed" else "a -> '$value'" } b.onReceiveOrNull { value -> if (value == null) "Channel 'b' is closed" else "b -> '$value'" } }

      注意,onReceiveOrNull 是?個僅在?于不可空元素的通道上定義的擴展函數(shù),以使關(guān)閉的通道與空值 之間不會出現(xiàn)意外的混亂。 現(xiàn)在有?個?成四次“Hello”字符串的 a 通道,和?個?成四次“World”字符串的 b 通道,我們在這 兩個通道上使?它:

      val a = produce { repeat(4) { send("Hello $it") } } val b = produce { repeat(4) { send("World $it") } } repeat(8) { // 打印最早的?個結(jié)果 println(selectAorB(a, b)) } coroutineContext.cancelChildren()

      這段代碼的結(jié)果?常有趣,所以我們將在細(xì)節(jié)中分析它:

      a -> 'Hello 0' a -> 'Hello 1' b -> 'World 0' a -> 'Hello 2' a -> 'Hello 3' b -> 'World 1' Channel 'a' is closed Channel 'a' is closed

      有?個結(jié)果可以通過觀察得出。

      ?先,select 偏向于 第?個?句,當(dāng)可以同時選到多個?句時,第?個?句將被選中。在這?,兩個通 道都在不斷地?成字符串,因此 a 通道作為 select 中的第?個?句獲勝。然?因為我們使?的是?緩 沖通道,所以 a 在其調(diào)? send 時會不時地被掛起,進(jìn)? b 也有機會發(fā)送。

      第?個觀察結(jié)果是,當(dāng)通道已經(jīng)關(guān)閉時,會?即選擇 onReceiveOrNull。

      Select 以發(fā)送

      Select 表達(dá)式具有 onSend ?句,可以很好的與選擇的偏向特性結(jié)合使?。

      我們來編寫?個整數(shù)?成器的?例,當(dāng)主通道上的消費者?法跟上它時,它會將值發(fā)送到 side 通道 上:

      fun CoroutineScope.produceNumbers(side: SendChannel) = produce { for (num in 1..10) { // ?產(chǎn)從 1 到 10 的 10 個數(shù)值 delay(100) // 延遲 100 毫秒 select { onSend(num) {} // 發(fā)送到主通道 side.onSend(num) {} // 或者發(fā)送到 side 通道 } } }

      消費者將會?常緩慢,每個數(shù)值處理需要 250 毫秒:

      val side = Channel() // 分配 side 通道 launch { // 對于 side 通道來說,這是?個很快的消費者 side.consumeEach { println("Side channel has $it") } } produceNumbers(side).consumeEach { println("Consuming $it") delay(250) // 不要著急,讓我們正確消化消耗被發(fā)送來的數(shù)字 } println("Done consuming") coroutineContext.cancelChildren()

      讓我們看看會發(fā)?什么:

      Consuming 1 Side channel has 2 Side channel has 3 Consuming 4 Side channel has 5 Side channel has 6 Consuming 7 Side channel has 8 Side channel has 9 Consuming 10 Done consuming

      Select 延遲值

      延遲值可以使? onAwait ?句查詢。讓我們啟動?個異步函數(shù),它在隨機的延遲后會延遲返回字符串:

      fun CoroutineScope.asyncString(time: Int) = async { delay(time.toLong()) "Waited for $time ms" }

      讓我們隨機啟動?余個異步函數(shù),每個都延遲隨機的時間。

      fun CoroutineScope.asyncStringsList(): List> { val random = Random(3) return List(12) { asyncString(random.nextInt(1000)) } }

      現(xiàn)在 main 函數(shù)在等待第?個函數(shù)完成,并統(tǒng)計仍處于激活狀態(tài)的延遲值的數(shù)量。注意,我們在這?使? select 表達(dá)式事實上是作為?種 Kotlin DSL,所以我們可以?任意代碼為它提供?句。在這種情況 下,我們遍歷?個延遲值的隊列,并為每個延遲值提供 onAwait ?句的調(diào)?。

      val list = asyncStringsList() val result = select { list.withIndex().forEach { (index, deferred) -> deferred.onAwait { answer -> "Deferred $index produced answer '$answer'" } } } println(result) val countActive = list.count { it.isActive } println("$countActive coroutines are still active")

      該輸出如下:

      Deferred 4 produced answer 'Waited for 128 ms' 11 coroutines are still active

      在延遲值通道上切換

      我們現(xiàn)在來編寫?個通道?產(chǎn)者函數(shù),它消費?個產(chǎn)?延遲字符串的通道,并等待每個接收的延遲值, 但它只在下?個延遲值到達(dá)或者通道關(guān)閉之前處于運?狀態(tài)。此?例將 onReceiveOrNull 和 onAwait ?句放在同?個 select 中:

      fun CoroutineScope.switchMapDeferreds(input: ReceiveChannel>) = produce { var current = input.receive() // 從第?個接收到的延遲值開始 while (isActive) { // 循環(huán)直到被取消或關(guān)閉 val next = select?> { // 從這個 select 中返回下?個延遲值或 null input.onReceiveOrNull { update -> update // 替換下?個要等待的值 } current.onAwait { value -> send(value) // 發(fā)送當(dāng)前延遲?成的值 input.receiveOrNull() // 然后使?從輸?通道得到的下?個延遲值 } } if (next == null) { println("Channel was closed") break // 跳出循環(huán) } else { current = next } } }

      為了測試它,我們將??個簡單的異步函數(shù),它在特定的延遲后返回特定的字符串:

      fun CoroutineScope.asyncString(str: String, time: Long) = async { delay(time) str }

      main 函數(shù)只是啟動?個協(xié)程來打印 switchMapDeferreds 的結(jié)果并向它發(fā)送?些測試數(shù)據(jù):

      val chan = Channel>() // 測試使?的通道 launch { // 啟動打印協(xié)程 for (s in switchMapDeferreds(chan)) println(s) // 打印每個獲得的字符串 } chan.send(asyncString("BEGIN", 100)) delay(200) // 充?的時間來?產(chǎn) "BEGIN" chan.send(asyncString("Slow", 500)) delay(100) // 不充?的時間來?產(chǎn) "Slow" chan.send(asyncString("Replace", 100)) delay(500) // 在最后?個前給它?點時間 chan.send(asyncString("END", 500)) delay(1000) // 給執(zhí)??段時間 chan.close() // 關(guān)閉通道…… delay(500) // 然后等待?段時間來讓它結(jié)束

      這段代碼的執(zhí)?結(jié)果:

      BEGIN Replace END Channel was closed
      本文名稱:kotlin協(xié)程——&gt;select表達(dá)式(實驗性的)-創(chuàng)新互聯(lián)
      轉(zhuǎn)載來于:http://ef60e0e.cn/article/jhhdd.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        呈贡县| 清远市| 乌鲁木齐县| 板桥市| 平原县| 绥化市| 天祝| 集贤县| 松江区| 静乐县| 乌兰察布市| 南澳县| 盖州市| 永福县| 东莞市| 土默特左旗| 昌黎县| 安塞县| 宁波市| 涟源市| 孟州市| 彰化市| 南靖县| 金山区| 体育| 商河县| 浮山县| 平邑县| 建平县| 达日县| 新野县| 历史| 秦安县| 教育| 蒲江县| 房山区| 嘉义市| 延吉市| 聂荣县| 海盐县| 莱州市|