Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
232 views
in Technique[技术] by (71.8m points)

kotlin - Better RXJava2 Maybe chaining

I must handle a Maybe in an async chain. In fact I want to send emails via an async mail client (vertx rxjava2 mail client)

The mail may have one attachment or not.

So I wrote a method:

private fun getAttachment() : Maybe<MailAttachment>

The code which uses this method looks like this:

private fun buildMail() : Single<MailMessage> {

    return getAttachment()
        .switchIfEmpty(Single.just(MailMessage()))
        .map { attachment ->
            val mail = MailMessage()
                .setFrom("...")
                ...

            if (attachment.name != null) {
               mail.setAttachment(attachment)
            }
        }
}

As you can see I switch to an empty new instance of a mail message when the maybe is empty but I dont really like this kind of creating an empty element and test in the map if the element is "filled".

I think there must be a better way of handling such kind of logic?!

One could put the attachment in a list and return a Single<List> and then test in the map if the list is empty, but that is not really a better approch in my opinion as this would look like there could be more then one attachment.

question from:https://stackoverflow.com/questions/65626650/better-rxjava2-maybe-chaining

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't usually use Maybe, but I believe that if you are just wanting remove the if, you can try something like this:

        getAttachment()
            .map { attachment ->
                // This only happens if Maybe returns a value
                val mail = MailMessage()
                mail.setAttachment(attachment)

                return@map mail
            }
            .toSingle(MailMessage())
            .map { mail ->
                mail.setFrom("...")
                // ...
            }
            .subscribe().addTo(disposables)

If you don't want to create MailMessage() in two places, then you can try something like this:

        Single.just(MailMessage().setFrom("..."))
            .flatMap { mail ->
                getAttachment()
                    .map { attachment ->
                        mail.apply {
                            this.attachment = attachment
                        }
                    }.toSingle(mail)
            }

The first approach is a little easier to read (in my opinion), but both should work


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...