RxJava switchMap不会取消先前的请求

时间:2018-12-27 06:37:43

标签: android kotlin rx-java okhttp

我正在使用Kotlin,OkHttp,RxJava2开发Android应用。

我正在尝试进行自动搜索。

当用户输入字符时,对其进行搜索。

override fun search(subject: PublishSubject<String>) {
    disposable.add(
            subject.debounce(1000, TimeUnit.MILLISECONDS)
                    .filter { it.isNotEmpty() }
                    .distinctUntilChanged()
                    .switchMap { keyword ->
                        search(keyword)
                    }
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe({ response ->
                        // using the response
                    }, {
                        it.printStackTrace()
                    })
    )
}

以及搜索功能:

    fun search(keyword: String): Observable<String> {
        val request = Request.Builder()
            .url(url)
            .post(RequestBody.create(contentType, xmlBody(keyword)))
            .build()

        return Observable.fromCallable {
            val response = OkHttpClient().newCall(request).execute()
            response.body()?.string()
        }
    }

我喜欢“ Retrofit”,但就我而言,我应该使用XML。 我尝试将Retrofit与SimpleXMLConverter一起使用,但是不适合该项目。 所以我正在使用“ OkHttp”。 但是上面的代码抛出“ InterruptedIOException”。

第一个电话可以。 但是,在处理第一个请求的同时收到下一个搜索请求时,会发生异常。

我该如何解决?

我认为,switchMap应该取消先前的请求,但不会。

1 个答案:

答案 0 :(得分:0)

您将调度程序设置为错误。

您需要:

    {% extends 'base.html' %}
    {% load static %}
    {% block content %}
    </br></br></br></br>
    <div class="content">
        <div class="row">
        <div class="col-md-2"></div>
        <div class="col-md-6">
             <form id="post_from" method="post">
                {% csrf_token %}
                <div class="form-group">
                 {{ form.as_p }}
                </div>
                <button type="submit" class="btn btn-primary">Upload</button>
             </form>
        </div>
            <div class="col-md-2"></div>
        </div>
        <div class="row"> </div>
        <div class="row"> </div>


    </div>
    {% endblock %} </pre></code>

}

请注意,后台调度程序需要直接在可搜索搜索中设置,而不是在override fun search(subject: PublishSubject<String>) { disposable.add( subject.debounce(1000, TimeUnit.MILLISECONDS) .filter { it.isNotEmpty() } .distinctUntilChanged() .switchMap { keyword -> search(keyword).subscribeOn(Schedulers.io()) } .observeOn(AndroidSchedulers.mainThread()) .subscribe({ response -> // using the response }, { it.printStackTrace() }) ) 之后的链中设置。 这是要在除主链以外的其他链中执行搜索,否则整个链将被阻塞,switchmap似乎没有任何效果,因为只有在自然完成后才会取消搜索。