【问题标题】:How to delay onError() in RxJava 2 and Android?如何在 RxJava 2 和 Android 中延迟 onError()?
【发布时间】:2018-05-15 18:27:38
【问题描述】:

我正在尝试从我的应用程序中的 Web 服务器加载一些数据。而且由于操作的异步性质,无法提前知道完成需要多长时间。为了提醒用户操作“正在进行中”,我使用了加载指示器。

这是使用 kotlin 和 RxJava 2 提出的(我希望它很清楚):

fun loadData(){

    showLoader() // show loading indicator

    Single.fromCallable {

        // http request logic goes here

    }.delay(1000, TimeUnit.MILLISECONDS)
     .subscribeOn(Schedulers.io())
     .observeOn(AndroidSchedulers.mainThread())
     .subscribeWith(object : DisposableSingleObserver<String>() {

            override fun onSuccess(data: String) {
                // do something
                hideLoader() // on success, hide indicator
            }

            override fun onError(e: Throwable) {
                displayErrorMessage()
                hideLoader() // on error hide indicator
            }

      })
}

我想显示加载指示器至少 1 秒,所以我使用了 delay() 运算符,但问题是如果操作成功,这将按预期工作,但如果出现错误,指示器将立即消失而不是1 秒后。

那么有没有办法让onError() 方法在 1 秒后执行?谢谢

【问题讨论】:

  • 你不能和Observable.timer(1, TimeUnit.SECONDS).switchMapSingle { Single.fromCallable { //... } }一起去吗?
  • mcassino 谢谢你这完美的作品。难道不能直接在 Single 上应用 timer() 操作符,而不是先将其转换为 Observable 吗?
  • 你可以 :) 我认为 Single.timer() 然后 map() 也是一种有效的方法。

标签: android kotlin delay rx-java2


【解决方案1】:

感谢nacassiano的评论,我终于找到了解决办法:

fun loadData(){

    showLoader() // show loading indicator

    Single.timer(1000, TimeUnit.MILLISECONDS)
        .flatMap{
            Single.fromCallable {

                // http request logic goes here

            }
        }.subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeBy( // this is an extension function from rxkotlin
            onSuccess = {
                // do something
                hideLoader() // on success, hide indicator
            },
            onError = {
                displayErrorMessage()
                hideLoader() // on error hide indicator
            }
       )
}

我希望这会对某人有所帮助。

【讨论】:

    【解决方案2】:

    由于您的工作是在后台线程中完成的,您可以直接休眠而不冻结 ui:

    SystemClock.sleep(1000)
    

    把它放在hideLoader() 调用之前

    【讨论】:

    • 好主意,但这不是delay() 应该做的吗?
    • 在延迟的文档中它说返回一个延迟源 ObservableSource 的发射的 Observable ..所以它延迟了发射,而不是执行。从理论上讲,您的代码可能会在我理解的延迟发射开始之前失败。
    【解决方案3】:

    只需调用不同的延迟方法签名

    public final Single<T> delay(long time, TimeUnit unit, boolean delayError)
    

    Single.fromCallable {
    
        // http request logic goes here
    
    }.delay(1000, TimeUnit.MILLISECONDS, true)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多