我正在尝试映射新数组,但是需要等到订阅完成后才能返回值。正确的方法是什么?我可以将这些转换为诺言吗?怎么样?
this.firebaseService.getPolls().pipe(first()).subscribe((fetchedPolls:any) => {
this.polls = fetchedPolls.filter(poll => poll.payload.doc.id == this.pollKey)
this.pollKey = this.polls[0].payload.doc.id;
this.firebaseService.getPollVotes(this.pollKey).subscribe((fetchedPollVotes:any) => {
this.pollVotes = fetchedPollVotes.map((poll:any) => {
let userKey = poll.payload.doc.get('user');
let choiceKey = poll.payload.doc.get('choice');
let username;
let players;
this.firebaseService.getUser(userKey).pipe(first()).subscribe((user:any) => {
username = user.payload.get('username');
});
this.firebaseService.getChoice(choiceKey).pipe(first()).subscribe((choice:any) => {
players = choice.payload.get('players');
});
return { username: username, choice: players }
})
});
});
firebase.service.ts
import { Injectable } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { map, switchMap, first } from 'rxjs/operators';
import { Observable, from } from 'rxjs';
import * as firebase from 'firebase';
import { AngularFireAuth } from '@angular/fire/auth';
@Injectable({
providedIn: 'root'
})
export class FirebaseService {
// Source: https://github.com/AngularTemplates/angular-firebase-crud/blob/master/src/app/services/firebase.service.ts
constructor(public db: AngularFirestore, private afAuth: AngularFireAuth) { }
getPolls() {
return this.db.collection('polls', ref => ref.orderBy('createdAt', 'desc')).snapshotChanges();
}
getPollVotes(pollKey) {
return this.db.collection('votes', ref => ref.where('poll', '==', pollKey).orderBy('createdAt', 'desc')).snapshotChanges();
}
getUser(userKey) {
return this.db.collection('users').doc(userKey).snapshotChanges();
}
getChoice(choiceKey) {
return this.db.collection('choices').doc(choiceKey).snapshotChanges();
}
}
**更新***
我尝试关注,但对此this.pollVotes不确定。另外,重要的一点是要保持this.firebaseService.getPollVotes的订阅有效,因为每次创建新的投票时我都需要更新该订阅。
this.firebaseService.getPolls().pipe(first()).toPromise().then((fetchedPolls:any) => {
this.polls = fetchedPolls.filter(poll => poll.payload.doc.id == this.pollKey)
this.pollKey = this.polls[0].payload.doc.id;
}).then(() => {
this.firebaseService.getPollVotes(this.pollKey).subscribe((fetchedPollVotes:any) => {
this.pollVotes = fetchedPollVotes.map((poll:any) => {
let userKey = poll.payload.doc.get('user');
let choiceKey = poll.payload.doc.get('choice');
let getUserObservable = this.firebaseService.getUser(userKey).pipe(catchError((err, caught) => of([])));
let getChoiceObservable = this.firebaseService.getChoice(choiceKey).pipe(catchError((err, caught) => of([])));
forkJoin([getUserObservable, getChoiceObservable])
.subscribe((results:any) => {
// results[0], results[1], result[2], result[3] is our response from services
console.log(results);
return { username: results[0].payload.get('username'), choice: results[1].payload.get('players')}
});
});
});
console.log("results", this.pollVotes);
});
}
**另一个更新**
我对函数进行了一些重新排列,现在我在this.pollVotes数组中得到两个条目,但是该数组对两个值都返回未定义的状态,因为forkJoin上的订阅从未被命中。换句话说,我的两个控制台日志语句从不注销。
this.firebaseService.getPolls().pipe(first()).subscribe((fetchedPolls:any) => {
this.polls = fetchedPolls.filter(poll => poll.payload.doc.id == this.pollKey)
this.pollKey = this.polls[0].payload.doc.id;
this.firebaseService.getPollVotes(this.pollKey).subscribe((fetchedPollVotes:any) => {
this.pollVotes = fetchedPollVotes.map((poll:any) => {
let userKey = poll.payload.doc.get('user');
let choiceKey = poll.payload.doc.get('choice');
let getUserObservable = this.firebaseService.getUser(userKey).pipe(catchError((err, caught) => of([])));
let getChoiceObservable = this.firebaseService.getChoice(choiceKey).pipe(catchError((err, caught) => of([])));
forkJoin([getUserObservable, getChoiceObservable])
.subscribe((results:any) => {
// results[0], results[1], result[2], result[3] is our response from services
console.log("username", results[0].payload.get('username'));
console.log("players", results[1].payload.get('players'));
return { username: results[0].payload.get('username'), choice: results[1].payload.get('players')}
});
});
console.log("results", this.pollVotes);
});
});
答案 0 :(得分:0)
您可以使用rxjs-forkjoin来实现。这是您的案例的一个小例子,
let getPollsObservable = this.fireBaseService.getPolls().pipe(catchError((err, caught) => of([])));
let getPollVotesObservable = this.fireBaseService.getPollVotes(pollKey).pipe(catchError((err, caught) => of([])));
let getUserObservable = this.fireBaseService.getUser(userKey).pipe(catchError((err, caught) => of([])));
let getChoiceObservable = this.fireBaseService.getChoice(choiceKey).pipe(catchError((err, caught) => of([])));
this.getServiceSubscription = forkJoin([getPollsObservable, getPollVotesObservable, getUserObservable, getChoiceObservable])
.subscribe(results => {
// results[0], results[1], result[2], result[3] is our response from services
console.log(result);
});
答案 1 :(得分:0)
解决了以下问题:
ngOnInit() {
this.getPollData();
}
async getPollData() {
let fetchedPolls = await this.firebaseService
.getPolls()
.pipe(first())
.toPromise();
this.polls = fetchedPolls.filter(
poll => poll.payload.doc.id == this.pollKey
);
this.pollKey = this.polls[0].payload.doc.id;
this.getPollVotesData();
}
async getPollVotesData() {
try {
let getPollVotesProc = this.firebaseService
.getPollVotes(this.pollKey)
.pipe(first())
.toPromise();
let fetchedPollVotes = await getPollVotesProc;
fetchedPollVotes.map(async (poll: any) => {
let userKey = poll.payload.doc.get("user");
let choiceKey = poll.payload.doc.get("choice");
let username;
let players;
let user = await this.firebaseService
.getUser(userKey)
.pipe(first())
.toPromise();
let choice = await this.firebaseService
.getChoice(choiceKey)
.pipe(first())
.toPromise();
players = choice.payload.get("players");
username = user.payload.get("username");
this.pollVotes.push({ username: username, choice: players });
return { username: username, choice: players };
});
} catch (error) {
console.log(error);
}
}