我在kotlin的協程使用過程當中,其實發現了不少rxjava和協程之間很類似的地方。java
若是把兩個東西孤立起來學習,我以爲成本過高了。把類似的地方剝離出來理解,我以爲經過這種方式吧,能夠把學習的成本大大的縮減下來。面試
下面給你們分享下個人一部分見解。編程
由於不知道爲啥面試官喜歡問背壓,那麼我就用來Flowable舉例子好了。bash
我至今沒有碰到過任何關於背壓的問題,有碰到朋友能夠留言交流下
先說業務場景,有個頁面要處理onActivityResult方法,可是我只有context實例,若是從activity一層層傳遞下來我又不開心,這個時候咋辦。app
object RxResult {
fun startForResult(activity: AppCompatActivity, requestCode: Int, targetActivity: Class<out Activity>): Flowable<Boolean> {
val fragment = EmptyFragment()
fragment.targetActivity = targetActivity
fragment.requestCode = requestCode
val flowable = Flowable.create(fragment, BackpressureStrategy.LATEST)
activity.supportFragmentManager.beginTransaction().add(fragment, "empty").commit() return flowable
}
}
class EmptyFragment : Fragment(), FlowableOnSubscribe<Boolean> {
private var emitter: FlowableEmitter<Boolean>? = null
var requestCode: Int = 1234
var targetActivity: Class<out Activity>? = null
override fun subscribe(emitter: FlowableEmitter<Boolean>) {
this.emitter = emitter
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
targetActivity?.apply {
val intent = Intent(context, targetActivity)
startActivityForResult(intent, requestCode)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
emitter?.onNext(resultCode == Activity.RESULT_OK)
}
}複製代碼
上述的邏輯操做徹底都是異步的,由於咱們只知道了方法被調用到了,簡單的說onActivityResult 函數觸發了以後,咱們調用了emmiter發射器的onNext 方法。異步
以後咱們構建的Flowable就會接受到對應的回調了。這樣咱們就能把一個異步的操做,構建成一個流式的操做,對於調用方來講他們根本不關心咱們內部是如何彎彎繞繞,他們只關心他們下游的流須要的後續操做就好了。ide
這個地方只是隨手寫的啊,可能會有bug的
在異步編程中,回調是很是常見的寫法,那麼如何將回調轉換爲協程中的掛起函數呢?能夠經過兩個掛起函數suspendCoroutine{}
或suspendCancellableCoroutine{}。
異步編程
這兩個函數就是協程給咱們提供的將異步回調寫成掛起函數的方式。函數
private suspend inline fun loadLottie(url: String): LottieComposition? {
return suspendCancellableCoroutine { continuation ->
var resumed = false
val task = LottieCompositionFactory.fromUrl(getContext(), url, LottieHelper.getCacheKey(url))
task.addListener {
if (!resumed || continuation.isActive) {
continuation.resume(it)
resumed = true
}
}
task.addFailureListener {
continuation.resumeWithException(it)
}
}
}複製代碼
仍是用以前加載lottie的代碼來介紹,其中CancellableContinuation就是和emitter同樣的一個發射器, continuation.resume(it)這個方法咱們能夠類比成emitter的onNext方法,而後當協程接受到這個值的狀況下,纔會從新喚起下一步的執行。學習
我我的見解,二者其實實現思路都是同樣的,經過傳輸一個發射器給一個異步方法,而後由最後的結果發射回給調用方使用。
可是吧,若是如今讓我選,我仍是以爲協程真香,畢竟鏈式調用一旦過長的狀況下,其實對於開發的能力要求就越高。而kotlin協程的寫法起碼看起來更像是順序執行,可讀性和可維護性其實對後續來講會更好一點。
若是各位以爲有幫助請幫忙轉發點贊,辣雞做者先賺點知名度。
下次我應該會寫下關於協程的dispatcher和rxjava的Schedulers,我以爲這兩個東西也仍是很類似的。