带有协程的嵌套回调函数
Nested Callback function with coroutines
我想使用 kotlin 协同程序从 javascript 风格的回调函数 async/await 获得响应。
这是我的回调函数
offlineCatalog.findOfflineVideoById(id, object : OfflineCallback<Video> {
override fun onSuccess(video: Video?) {
video?.let {
//Return This Video
} ?: kotlin.run {
findVideoOnline(id, state)
}
}
override fun onFailure(throwable: Throwable?) {
findVideoOnline(id, state)
}
})
onlineCatalog.findVideoByID(id, object : VideoListener() {
override fun onVideo(video: Video?) {
video?.let {
//Return This Video
} ?: kotlin.run {
Log.e("Return Error")
}
}
override fun onError(errors: MutableList<CatalogError>) {
super.onError(errors)
Log.e("Return Error")
}
})
如果 OfflineCatalog
出错,我想调用 return 来自 OfflineCatalog
视频对象的函数,然后从 OnlineCatalog
.
搜索
比如
try{
val video:Video? = getVideo(id:String)
//do something
}catch(throwable:Throwable){
Log.e("Video not found")
}
更新:我的实现n
这是我想出来的
suspend fun getVideo(id: String): Video? = withContext(Dispatchers.IO) {
var video = getVideoOffline(id)
video?.let { video } ?: kotlin.run { getVideoOnline(id) }
}
suspend fun getVideoOffline(id: String): Video? = suspendCancellableCoroutine { cont ->
(offlineCatalog.findOfflineVideoById(id, object : OfflineCallback<Video> {
override fun onSuccess(video: Video?) = cont.resume(video)
override fun onFailure(throwable: Throwable?) = cont.resume(null)
}))
}
suspend fun getVideoOnline(id: String): Video? = suspendCancellableCoroutine { cont ->
catalog.findVideoByID(id, object : VideoListener() {
override fun onVideo(video: Video?) = cont.resume(video)
override fun onError(errors: MutableList<CatalogError>) = cont.resume(null)
})
}
用法-
CoroutineScope(Dispatchers.Main).launch {
getVideo(id)?.let {
//Do Something
} ?: kotlin.run{
//Video Not Found
}
}
你必须这样做
@ExperimentalCoroutinesApi
suspend fun getVideo(id: String): Video? = coroutineScope {
val offlineVideo: Video? = suspendCancellableCoroutine { cont ->
offlineCatalog.findOfflineVideoById(id, object : OfflineCallback<Video> {
override fun onSuccess(video: Video?) {
cont.resume(video)
}
override fun onFailure(throwable: Throwable?) {
cont.resume(null)
}
})
}
offlineVideo ?: suspendCancellableCoroutine { cont ->
// offlineVideo not found so search from onlineCatalog
onlineCatalog.findVideoByID(id, object : VideoListener() {
override fun onVideo(video: Video?) {
cont.resume(video)
}
override fun onError(errors: MutableList<CatalogError>) {
super.onError(errors)
cont.resumeWithException(someException)
}
})
}
}
然后你就可以随便调用了
someScope.launch {
try {
val video: Video? = getVideo(id)
//do something
} catch (throwable: Throwable) {
Log.e("Video not found")
}
}
阅读更多关于 suspendCancellableCoroutine
here
我想使用 kotlin 协同程序从 javascript 风格的回调函数 async/await 获得响应。
这是我的回调函数
offlineCatalog.findOfflineVideoById(id, object : OfflineCallback<Video> {
override fun onSuccess(video: Video?) {
video?.let {
//Return This Video
} ?: kotlin.run {
findVideoOnline(id, state)
}
}
override fun onFailure(throwable: Throwable?) {
findVideoOnline(id, state)
}
})
onlineCatalog.findVideoByID(id, object : VideoListener() {
override fun onVideo(video: Video?) {
video?.let {
//Return This Video
} ?: kotlin.run {
Log.e("Return Error")
}
}
override fun onError(errors: MutableList<CatalogError>) {
super.onError(errors)
Log.e("Return Error")
}
})
如果 OfflineCatalog
出错,我想调用 return 来自 OfflineCatalog
视频对象的函数,然后从 OnlineCatalog
.
比如
try{
val video:Video? = getVideo(id:String)
//do something
}catch(throwable:Throwable){
Log.e("Video not found")
}
更新:我的实现n
这是我想出来的
suspend fun getVideo(id: String): Video? = withContext(Dispatchers.IO) {
var video = getVideoOffline(id)
video?.let { video } ?: kotlin.run { getVideoOnline(id) }
}
suspend fun getVideoOffline(id: String): Video? = suspendCancellableCoroutine { cont ->
(offlineCatalog.findOfflineVideoById(id, object : OfflineCallback<Video> {
override fun onSuccess(video: Video?) = cont.resume(video)
override fun onFailure(throwable: Throwable?) = cont.resume(null)
}))
}
suspend fun getVideoOnline(id: String): Video? = suspendCancellableCoroutine { cont ->
catalog.findVideoByID(id, object : VideoListener() {
override fun onVideo(video: Video?) = cont.resume(video)
override fun onError(errors: MutableList<CatalogError>) = cont.resume(null)
})
}
用法-
CoroutineScope(Dispatchers.Main).launch {
getVideo(id)?.let {
//Do Something
} ?: kotlin.run{
//Video Not Found
}
}
你必须这样做
@ExperimentalCoroutinesApi
suspend fun getVideo(id: String): Video? = coroutineScope {
val offlineVideo: Video? = suspendCancellableCoroutine { cont ->
offlineCatalog.findOfflineVideoById(id, object : OfflineCallback<Video> {
override fun onSuccess(video: Video?) {
cont.resume(video)
}
override fun onFailure(throwable: Throwable?) {
cont.resume(null)
}
})
}
offlineVideo ?: suspendCancellableCoroutine { cont ->
// offlineVideo not found so search from onlineCatalog
onlineCatalog.findVideoByID(id, object : VideoListener() {
override fun onVideo(video: Video?) {
cont.resume(video)
}
override fun onError(errors: MutableList<CatalogError>) {
super.onError(errors)
cont.resumeWithException(someException)
}
})
}
}
然后你就可以随便调用了
someScope.launch {
try {
val video: Video? = getVideo(id)
//do something
} catch (throwable: Throwable) {
Log.e("Video not found")
}
}
阅读更多关于 suspendCancellableCoroutine
here