代码之家  ›  专栏  ›  技术社区  ›  kip2

rxjava:在列表中创建项并返回新列表

  •  1
  • kip2  · 技术社区  · 7 年前

    这里是RX Noobie:你知道如何实现这个目标吗?:

    我有一个来自用户界面的项目列表,希望将它们发布到服务器。我需要从服务器发回的邮件列表(使用服务器发出的id、时间戳等)。

    请原谅我的长例子,但下面是我努力工作的代码:

    /**
     * create each item (POST) in the list and return the list
     * of newly created ones
     */
    fun postItems(items: List<Item>): Maybe<List<Item>> {
        // loop through all items, making a network call for each and return the
        // list of POSTed items
    
        // attempt 1
        // Failed type inference. Expected type mismatch:
        // Expected: Maybe<List<Item>>
        // Found: List<Maybe<Item>>
        return items.map {
            postItem(it)
        }
    
        // attempt 2: 'extract' each item in resulting observable and
        // shove it back to original list
        return Maybe.just(items.map {
            postItem(it!!)
                    // 'extract' item from observable
                    .flatMap {
                        // error: Type mismatch.
                        // Required ((Item) -> MaybeSource<out (???...???)>!)!
                        // Found (Item) -> Item
                        it
                    }
        })
    
        // attempt 3: convert a Maybe to Flowable to collect all items from post
        // and emit them as a single list
        // Type mismatch. Required:(((Mutable)List<Item!>) -> SingleSource<out (???...???)>!)!
        // Found: ((Mutable)List<Item!>) -> (Mutable)List<Item!>
        return items.forEach {
            postItem(it!!).toFlowable().toList().flatMap { it }
        }
    
        // attempt 4: modify attempt 3 with concatMap:
        // Type mismatch. Required:((List<Item!>) -> MaybeSource<out (???...???)>!)!
        // Found: (List<Item!>) -> List<Maybe<Item>>
        return Maybe.just(items)
                // wait for each observable to finish all the work 
                // until the next one is processed
                .concatMap({
                    it.map { addItem(it!!) }
                }).toFlowable()
                .toList().toMaybe()
    
        // attempt 6: blocking call on each API request.
        // results in android.os.NetworkOnMainThreadException
        return Maybe.just(places.map {
            addPlace(it!!).blockingGet()
        })
    }
    
    fun postItem(item: Item): Maybe<Item> {
        return networkService.post(item) // async call to API, returns Maybe<Item>
    }
    

    更新

    我尝试过下面@alexeysoshin建议的方法,但仍有一些困惑:

    我尝试了第二种较短的方法,但由于某些原因,改造调用没有通过:(,即网络服务终结点未命中)。因为我不能让rx kotlin包装器工作,所以它稍微修改了一下,但我想它大致相当于:

    fun addItems(items: List<Item?>): Flowable<Maybe<Item>> {
        return Flowable.fromIterable(items).map {
            // tried items.toFlowable().map but got 'Unresolved reference toFlowable
            // even after adding rx-kotlin to project via gradle
            return@map postItem(it)
        }
    }
    

    “我的网络服务”可以成功地为具有以下代码的单个项目工作:

    // works as expected
    fun postOneItem(item: Item): Maybe<Item> {
        return postItem(item)
    }
    
    // also works
    fun postOneItemFlowable(item: Item): Flowable<Item> {
        return postItem(item).toFlowable()
    }
    
    
    // this variant didn't work
    fun postOneItemFlowable(item: Item): Flowable<Maybe<Item>> {
        return Flowable.just(postItem(item))
    }
    

    如何制作 Flowable<Maybe<Item>> 电话接通成功吗?(或) Flowable<List<Item>> ,最终会更接近我的需要)

    最后,如何从 可流动的<可能<项目>> ?这将有助于了解 .subscribe() block可能看起来像是“提取”最后一个列表。下面是我当前订阅代码的外观:

    ...
    private fun createItem(item: Item) {
        disposables.add(
                addItemUseCase.postOneItem(item)
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe({
                            Timber.d("one item posted: $it")
                        }, { /* error handler *//})
    }
    ...
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Alexey Soshin    7 年前

    你可以这样做:

    fun postItems(items: List<Item>): Maybe<List<Item>> {
        return items.toFlowable().map {
            postItem(it).blockingGet()
        }.toList().toMaybe()
    }
    

    但我不确定你的意思是什么 Maybe 不是 也许吧 ,实际上。

    这样更改签名会更有意义:

    fun postItems(items: List<Item>): Flowable<Maybe<Item>> {
        return items.toFlowable().map {
            postItem(it)
        }
    }