为 Completables 的动态列表创建单个 onComplete
Create single onComplete for dynamic list of Completables
我正在使用 this 库用 RxJava 包装 Firebase 事务。我是 RxJava 的新手,所以这主要是关于如何使用它的问题。
场景:Person
和Label
之间存在多对多关系。一个Person
可以有多个Label
,一个Label
可以给很多Person
。创建 Person
时,我必须:
- 将它们添加到
Person
的列表中
- 更新给他们的每个
Label
以允许查询属于特定标签的所有 Persons
我有一个 Label
的列表,我想写入我的 Firebase 数据库。
List<Label> labels; // Let's assume it's been instantiated and added to
我想把这些都写到数据库中:
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference peopleRef = database.getReference().child("people");
DatabaseReference labelsRef = database.getReference().child("labels");
int newPersonId = peopleRef.push().getKey();
如果我不关心调用是否成功,我可以轻松做到这一点。
// Let's assume I already saved the Person to the DB
for (Label label : labels){
// For each label, index the Person saved (Looks like 'personId: true')
labelsRef.child(label).child(newPersonId).setValue(true);
}
但是如果我关心结果怎么办?如果我想对所有正在更新的 Label
做出反应(比如离开当前的 Activity
),我需要知道它们是否都已成功更新。
RxFirebase 的实现方式是在数据库中设置一个值 returns a Completable
。我基本上想将 n
个 Completables 压缩在一起,并且只在它们成功或失败时才做一些事情。
到目前为止,如果我只想更新一个 Label
,我可以这样做,但我想更新 n
Label
s.
以下代码片段将 2 个 Completables 链接在一起,但只保存了 1 个 Label
RxFirebaseDatabase.setValue(peopleRef.child(newPersonId), person) // Save the Person
.andThen(RxFirebaseDatabase.setValue(labelsRef.child(label).child(newPersonId), true)) // I can index 1 Label, and this returns a Completable
我该怎么做?如果您足够了解 Firebase,这是否是保存项目列表的正确方法?
如果我对你的主要问题的理解正确,你有一组 Completable
,你需要将它们作为一个订阅。
解决这个问题的方法是使用 Completable.concat
或 Completable.merge
运算符。
Completable.concat: Returns a Completable which completes only when all sources complete, one after another.
Completable.merge: Returns a Completable instance that subscribes to all sources at once and completes only when all source Completables complete or one of them emits an error.
示例:
List<Completable> tasks; // initialized elsewhere
Completable
.concat(tasks)
.subscribe(
() -> Log.d(TAG, "All successful"),
throwable -> Log.w(TAG, "One or more failed"))
关于你的第二个问题,我对Firebase不是很了解。
更新:要获得List<Completable>
你可以做类似的事情:
List<Completable> tasks = new ArrayList<>();
for ( ... ) {
tasks.add(RxFirebaseDatabase.setValue(peopleRef.child(newPersonId), person));
}
Completable.concat(tasks).etc
我正在使用 this 库用 RxJava 包装 Firebase 事务。我是 RxJava 的新手,所以这主要是关于如何使用它的问题。
场景:Person
和Label
之间存在多对多关系。一个Person
可以有多个Label
,一个Label
可以给很多Person
。创建 Person
时,我必须:
- 将它们添加到
Person
的列表中 - 更新给他们的每个
Label
以允许查询属于特定标签的所有Persons
我有一个 Label
的列表,我想写入我的 Firebase 数据库。
List<Label> labels; // Let's assume it's been instantiated and added to
我想把这些都写到数据库中:
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference peopleRef = database.getReference().child("people");
DatabaseReference labelsRef = database.getReference().child("labels");
int newPersonId = peopleRef.push().getKey();
如果我不关心调用是否成功,我可以轻松做到这一点。
// Let's assume I already saved the Person to the DB
for (Label label : labels){
// For each label, index the Person saved (Looks like 'personId: true')
labelsRef.child(label).child(newPersonId).setValue(true);
}
但是如果我关心结果怎么办?如果我想对所有正在更新的 Label
做出反应(比如离开当前的 Activity
),我需要知道它们是否都已成功更新。
RxFirebase 的实现方式是在数据库中设置一个值 returns a Completable
。我基本上想将 n
个 Completables 压缩在一起,并且只在它们成功或失败时才做一些事情。
到目前为止,如果我只想更新一个 Label
,我可以这样做,但我想更新 n
Label
s.
以下代码片段将 2 个 Completables 链接在一起,但只保存了 1 个 Label
RxFirebaseDatabase.setValue(peopleRef.child(newPersonId), person) // Save the Person
.andThen(RxFirebaseDatabase.setValue(labelsRef.child(label).child(newPersonId), true)) // I can index 1 Label, and this returns a Completable
我该怎么做?如果您足够了解 Firebase,这是否是保存项目列表的正确方法?
如果我对你的主要问题的理解正确,你有一组 Completable
,你需要将它们作为一个订阅。
解决这个问题的方法是使用 Completable.concat
或 Completable.merge
运算符。
Completable.concat: Returns a Completable which completes only when all sources complete, one after another.
Completable.merge: Returns a Completable instance that subscribes to all sources at once and completes only when all source Completables complete or one of them emits an error.
示例:
List<Completable> tasks; // initialized elsewhere
Completable
.concat(tasks)
.subscribe(
() -> Log.d(TAG, "All successful"),
throwable -> Log.w(TAG, "One or more failed"))
关于你的第二个问题,我对Firebase不是很了解。
更新:要获得List<Completable>
你可以做类似的事情:
List<Completable> tasks = new ArrayList<>();
for ( ... ) {
tasks.add(RxFirebaseDatabase.setValue(peopleRef.child(newPersonId), person));
}
Completable.concat(tasks).etc