好的,所以我想做的是从firebase收集一个user_uid的列表,然后为每个user_uid获取一个图像URL并将其组合并返回一个Object。我遇到的问题是从异步调用返回对象。我正在尝试实现rxjava来实现这一点,但是我仍在获取空对象。下面我将提供代码和数据库结构,以便您可以看到我要实现的目标,在此先感谢所有帮助

这是数据库结构:
java - 使用RxJava从异步调用返回值?-LMLPHP

异步调用:

private Note createNoteWithArtists(Note note, ArrayList<String> user_uids) {
    DatabaseReference db_users = db_root.child("Users");
    ArrayList<User> artists = new ArrayList<>();
    Note note = note;
    for (String each_uid : user_uids) {
        db_users.child(each_uid).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                String uid = dataSnapshot.getKey();
                String image = dataSnapshot.child("image").getValue(String.class);
                String username = dataSnapshot.child("username").getValue(String.class);
                User user = new User(username, null, image, uid);
                artists.add(user);
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
    }
    note.setArtists(artists);
    return Note;
}


尝试使用RxJava:

io.reactivex.Observable<Note> observable = io.reactivex.Observable.create(subscriber -> {
                subscriber.onNext(createNoteWithArtists(note, artists));
                subscriber.onComplete();
            });
            observable.subscribe(note -> loadNoteResults.NoteLoaded(note, true)).dispose();


它返回注释,但是嵌套的artist对象仍然为空:/

最佳答案

一旦Observable.create(...)返回值,Note将发出createNotWitArtists。您的RxJava尝试在功能上等效于:

Note emptyNote = createNoteWithArtists(note, artists);
loadNoteResults.NoteLoaded(emptyNote , true);


看一下这种方法:

private Single<User> getUser(String user_uid) {
    DatabaseReference db_users = db_root.child("Users");
    return Single.create(emitter -> {
        db_users.child(each_uid).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                String uid = dataSnapshot.getKey();
                String image = dataSnapshot.child("image").getValue(String.class);
                String username = dataSnapshot.child("username").getValue(String.class);
                User user = new User(username, null, image, uid);
                emitter.onSuccess(user);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                emitter.onError(databaseError);
            }
        });
    });
}


这个想法是使用Single.create,它在每个onDataChange被调用时发出。

然后,您可以像这样使用Single组合所有toList()

// Note note
// List<String> artist

Observable.fromIterable(artistIds) // Observable<String>
    .flatMapSingle(this::getUser) // Observable<User>
    .toList() // Single<List<User>>
    .subscribe( artists -> {
        note.setArtists(artists);
        loadNoteResults.NoteLoaded(note, true);
    });


另外,不要忘记在需要时放置调度程序。

07-24 09:50
查看更多