RxJava:Insert只适用于Single,而不适用于Completable

3

我有两个 DAO 函数用于插入新用户:

@Insert(onConflict = OnConflictStrategy.REPLACE)
Completable addData(User user);

@Insert(onConflict = OnConflictStrategy.REPLACE)
Single<Long> insert(User user);

区别在于一个函数返回一个completable,而另一个函数返回一个Single<Long>,其中Long等于新插入用户的ID。

相应的ViewModel函数:

public Completable addData(User modelClass) {
    return Completable.fromAction(() -> appDatabase.userDao().addData(modelClass))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
}

public Single<Long> addData2(User user) {
    return appDatabase.userDao().insert(user)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
}

最后,在我的Android活动中,subscribe方法如下:
viewModel.addData(new User( ""+myEntireName.getText().toString(), "jlk"))
.subscribe(
() -> { 
 Toast.makeText(this, "Jähgermeister!!!!!", Toast.LENGTH_LONG).show();
}, 
throwable -> {
Toast.makeText(this, "Error!" + throwable.getMessage(), Toast.LENGTH_SHORT).show();
});

viewModel.addData2(new User( ""+myEntireName.getText().toString(), "jlk"))
.subscribe(
newI -> { //onSucess
Toast.makeText(this, "Yeah i work: " + newI, Toast.LENGTH_LONG).show();
}, //onError
throwable -> {
Toast.makeText(this, "Error!" + throwable.getMessage(), Toast.LENGTH_SHORT).show();
});

所遇到的问题是:返回 Completable 的插入函数会打印 Toast 消息,但实际上用户并没有被插入。但如果使用返回 Single<Long> 的函数,则用户会被插入。删除也是同样的情况。
可能的原因是什么?插入只能使用 Single<Long> 吗?
1个回答

2

这一行是问题的源头:

return Completable.fromAction(() -> appDatabase.userDao().addData(modelClass))

appDatabase.userDao().addData()返回一个Completable。将其放入fromAction()中意味着您不会订阅它返回的Completable,这意味着它应该完成的任何工作实际上都不会发生。您需要使用类似于Completable.defer(() -> ...)的东西,它将实际订阅调用addData返回的Completable


谢谢,那解决了我的问题。defer函数是不好的实践吗?在插入时使用会有问题吗? - Nummer Eins
1
defer 只是让 Dao 的 addData 方法在 Completable 被订阅之前不会被调用。如果你在 addData 内部进行的操作不是延迟(lazy),那么你通常只需要这个。如果 addData 是延迟的,那么你可以完全省略 defer 调用。 - dano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接