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

RxJava:如何返回正确的null类型

  •  4
  • jackcar  · 技术社区  · 7 年前

    我正在使用Firebase、Kotlin和RxJava开发一个应用程序。

    直到现在我都有这个

    RxFirebaseAuth.createUserWithEmailAndPassword(auth, email, password)
                .map { authResult ->
                    user.uid = authResult.user.uid
                    authResult.user.uid
                }
                .flatMap<UploadTask.TaskSnapshot>(
                        { uid ->
                            if (imageUri != null)
                                RxFirebaseStorage.putFile(mFirebaseStorage
                                        .getReference(STORAGE_IMAGE_REFERENCE)
                                        .child(uid), imageUri)
                            else
                                Maybe.empty<UploadTask.TaskSnapshot>()
                        }
                )
                .map { taskSnapshot -> user.photoUrl = taskSnapshot.downloadUrl!!.toString() }
                .map {
                    RxFirebaseDatabase
                            .setValue(mFirebaseDatabase.getReference("user")
                                    .child(user.uid), user).subscribe()
                }
                .doOnComplete { appLocalDataStore.saveUser(user) }
                .toObservable()
    

    当用户选择一张照片时,它工作正常,但当它未被选择时,其他地图被忽略,因为我可能返回了。空()。

    谢谢

    1 回复  |  直到 7 年前
        1
  •  2
  •   Sachin Chandil    7 年前

            val temp = null
            Observable.just("some value")
                    .flatMap {
                        // Throw exception if temp is null
                        if (temp != null) Observable.just(it) else Observable.error(Exception("")) 
                    }
                    .onErrorReturnItem("") // return blank string if exception is thrown
                    .flatMap { v ->
                        Single.create<String>{
                            // do something
                            it.onSuccess("Yepeee $v");
                        }.toObservable()
                    }
                    .subscribe({
                        System.out.println("Yes it worked: $it");
                    },{
                        System.out.println("Sorry: $it");
                    })
    

    如果遇到null,应该抛出一个错误,然后使用 onErrorReturn{} onErrorReturnItem() onError Observer

    因此,您的代码应该如下所示:

    RxFirebaseAuth.createUserWithEmailAndPassword(auth, email, password)
                    .map { authResult ->
                        user.uid = authResult.user.uid
                        authResult.user.uid
                    }
                    .flatMap<UploadTask.TaskSnapshot>(
                            { uid ->
                                if (imageUri != null)
                                    RxFirebaseStorage.putFile(mFirebaseStorage
                                            .getReference(STORAGE_IMAGE_REFERENCE)
                                            .child(uid), imageUri)
                                else
                                    Observable.error<Exception>(Exception("null value")) // Throw exception if imageUri is null
                            }
                    )
                    .map { taskSnapshot -> user.photoUrl = taskSnapshot.downloadUrl!!.toString() }
                    .onErrorReturn {
                        user.photoUrl = "" // assign blank url string if exception is thrown
                    }
                    .map {
                        RxFirebaseDatabase
                                .setValue(mFirebaseDatabase.getReference("user")
                                        .child(user.uid), user).subscribe()
                    }
                    .doOnComplete { appLocalDataStore.saveUser(user) }
                    .toObservable()
    

    但这段代码有一个问题,以前发生过任何异常 onErrorReturn 将生成一个空白uri,并导致我们不希望的进一步链执行。如果发生任何其他异常,则应调用一个错误。

    . 请看以下代码段:

    ...
    ...
    
    .flatMap<UploadTask.TaskSnapshot>(
                            { uid ->
                                if (imageUri != null)
                                    RxFirebaseStorage.putFile(mFirebaseStorage
                                            .getReference(STORAGE_IMAGE_REFERENCE)
                                            .child(uid), imageUri)
                                else
                                    Observable.error<MyCustomException>(MyCustomException("null value")) // Throw exception if imageUri is null
                            }
                    )
                    .map { taskSnapshot -> user.photoUrl = taskSnapshot.downloadUrl!!.toString() }
                    .onErrorReturn {
                        if(it !is MyCustomException)
                            throw it
                        else
                            user.photoUrl = "" // assign blank url string if exception is thrown
    
                    }
    ...
    ...