RxJava2。对列表中的每个项目执行请求

Posted

技术标签:

【中文标题】RxJava2。对列表中的每个项目执行请求【英文标题】:RxJava2. Execute a request for every item in a list 【发布时间】:2018-10-21 22:41:21 【问题描述】:

我有一个列表List<FileModel>

FileModel 只是一个包含id: Int 的类

id - 是我需要获取并投射到位图的照片文件的 ID

我有一个请求:

fun getFile(fileId: Int): Single<ResponseBody>

此请求返回ResponseBody,我们可以将其转换为位图

fun generatePhoto(responseBody: ResponseBody): Single<Bitmap?>

我想要的是创建一个函数

fun getPhotos(list: List<FileModel>): Single<List<Bitmap>> 
    // Execute getFile(...) for each item in the list
    // Cast getFile(...) result to Bitmap using generatePhoto(...)
    // Return a list of Bitmaps

我尝试过类似的方法,但完全错误

fun getPhotos(list: List<FileModel>): Single<List<Bitmap>> 
    return Observable.fromIterable(list)
        .flatMap  getFile(it.id) 
        // How to call generatePhoto(...) here?

【问题讨论】:

我不是 Rx 专家,你能举个例子吗? 其实应该就是flatMap吧。 【参考方案1】:

你可以这样做:

fun getPhotos(list: List<FileModel>): Single<List<Bitmap>> 
    // Get an Observable of the list
    return Observable.fromIterable(list)
        // Get a Single<ResponseBody> for every FileModel
        .flatMapSingle  getFile(it.id) 
        // Get a Single<Bitmap> for every ResponseBody
        .flatMapSingle  file -> generatePhoto(file) 
        // Put everything back on a list
        .toList()

通过这种方式,您可以根据需要遍历列表flapMapping,然后最后将其重新组合为列表。 toList() 运算符只是为了方便将之前发出的项放在一起。

然后调用这个函数就可以了:

    getPhotos(list)
        .doOnSuccess  resultList ->
          Log.d("Rx", "doOnSuccess.resultList=[$resultList]")
        
        .subscribe()

顺便说一句,如果您有 RxKotlin 作为依赖项,您可以从带有扩展功能的 List 获得 Observable,如下所示: myList.toObservable()

【讨论】:

【参考方案2】:

Observable.fromIterable(list) 应该为列表中的每个项目发出一个事件,这意味着您在 getPhotos 中的返回类型为Flowable&lt;Bitmap&gt;,因为 Flowable 可以返回多个值。

我想你真正想要的是:

fun getPhotos(list: List<FileModel>): Flowable<Bitmap> 
    return Observable.fromIterable(list)
        .map  getFile(it.id) 
        .map  generatePhoto(it) 

如果你想发出一个位图列表,你可以像这样使用单个

fun getPhotos(list: List<FileModel>): Single<List<Bitmap>> 
    return Single.just(list)
        .map  it.map  getFile(it.id)  
        .flatMap  
            Single.just(it.map  generatePhoto(it) ) 
        

【讨论】:

但是如果我们在 map 中使用 Single.just(list) 我们将使用 List 而不是 FileModel 我已经更新了答案,您可以遍历地图块内的每个列表 您可以使用 flatMap 来评估单曲,但在这种情况下您必须发出另一个单曲【参考方案3】:

你试过了吗:

fun getPhotos(list: List<FileModel>): Single<List<Bitmap>> 
    return Observable.fromIterable(list)
        .flatMapSingle  getFile(it.id) 
        .flatMapSingle  generatePhoto(it) 

?

【讨论】:

我们不能在 flatMap 之后调用 flatMapSingle 你是对的,也许两者都应该是flatMapSingle

以上是关于RxJava2。对列表中的每个项目执行请求的主要内容,如果未能解决你的问题,请参考以下文章

LINQ:根据某些条件过滤项目列表,并按条件执行某些操作

另一个列表中列表中项目的扩展方法[重复]

WPF DataGrid在同一列中的不同控件 - 不正确的绑定

VB.NET - 对于列表视图中的每个选中项目

两个异步请求成功后执行第三个异步函数

RxJava在项目中的特殊使用场景