Rx Java цепочка, наблюдаемая при загрузке - PullRequest
0 голосов
/ 25 января 2020

У меня есть объект, который может содержать URL-адреса

class MyObject
(
    var url_image:String? = null,
    var url_document:String? = null,
    var file_image:File? = null,
    var file_document:File? = null
)

Также у меня есть метод для загрузки URL-адресов, этот метод возвращает Observable<File>

fun download_file(url:String): Observable<File>
{
     //Some logic for creating file, downloading data from url and returning this file as Observable
}

Мне нужно создать метод где я передаю myObject, и при необходимости он загружает URL-адреса и, наконец, возвращает Observable<MyObject>. Примерно так:

fun prepareForShare(obj: MyObject): Observable<MyObject>
{
    return Observable.just(obj)
            .map(
                {
                    if (obj.url_image != null)
                    {
                        download_file(obj.url_image!!)
                        ...
                        .subscribe(
                        {
                            obj.file_image = it
                        })
                    }

                    if (obj.url_document != null)
                    {
                        download_file(obj.url_image!!)
                        ...
                        .subscribe(
                        {
                            obj.file_document = it
                        })
                    }
                }))
}

Как правильно составить цепочку запросов?

1 Ответ

1 голос
/ 25 января 2020

Вы можете объединить все запросы с помощью оператора zip(...) и преобразовать MyObject в обратном вызове flatMap{...}:

fun prepareForShare(obj: MyObject): Observable<MyObject> {
    return Observable.zip(
        if (obj.url_image != null) {
            download_file(obj.url_image!!).flatMap { 
                obj.file_image = it
                return@flatMap Observable.just(obj)
            }
        } else Observable.just(obj),
        if (obj.url_document != null) {
            download_file(obj.url_document!!).flatMap { 
                obj.file_document = it
                return@flatMap Observable.just(obj)
            }
        } else Observable.just(obj),
        BiFunction { o1, o2 ->
            obj.file_image = o1.file_image
            obj.file_document = o2.file_document
            obj
        }
    )
}

В качестве альтернативы , для более чистого подхода, Вы можете обернуть File в свой объект-держатель. Например:

data class MyFile(var file: File?)

и emit MyFile(null), если url пуст:

fun download_file(url:String?): Observable<MyFile>
{
    if (url == null) return Observable.just(MyFile(null))
    ...
}

fun prepareForShare(obj: MyObject): Observable<MyObject> {
    return Observable.zip(
        download_file(obj.url_image),
        download_file(obj.url_document),
        BiFunction { file1, file2 ->
            obj.file_image = file1.file
            obj.file_document = file2.file
            obj
        }
    )
}
...