Использование RxJava для возврата значения из асинхронного вызова? - PullRequest
0 голосов
/ 08 февраля 2019

Хорошо, я пытаюсь собрать список user_uid из firebase, а затем для каждого user_uid получить URL-адрес изображения, объединить его и вернуть один объект.Проблема, с которой я сталкиваюсь, заключается в возврате объекта из асинхронного вызова.Я пытаюсь реализовать rxjava для достижения этой цели, но я все еще получаю пустые объекты.ниже у меня будет код и структура базы данных, чтобы вы могли видеть, чего я пытаюсь достичь, спасибо всем заранее за любую помощь

это структура базы данных: http://oi63.tinypic.com/hsmio6.jpg

Асинхронный вызов:

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();

Возвращает заметку, но вложенный объект исполнителей все еще пуст: /

1 Ответ

0 голосов
/ 09 февраля 2019

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);
    });

Кроме того, не забывайте ставить планировщики всякий раз, когда это необходимо.

...