Angular 只运行一次订阅
我只需要运行一次Angular 只运行一次订阅,angular,typescript,rxjs,observable,google-cloud-firestore,Angular,Typescript,Rxjs,Observable,Google Cloud Firestore,我只需要运行一次userProfiles$.subscribe(async res=>{),但它可以无限工作。你能告诉我如何避免它吗 这是: .ts 版本: 承诺方式: 首先将其转换为promise,然后通过。然后()方法收听它,并等待已解决的promise 可观察的。采取(1) 注意,对于toPromise方法,不要忘记从rxjs操作符导入toPromise,对于take方法,也应该从rxjs导入take方法 更新。角度版本>=6 从angular 6开始,要求rxjs>=6。在该函数中,现在
userProfiles$.subscribe(async res=>{
),但它可以无限工作。你能告诉我如何避免它吗
这是:
.ts
版本:
承诺方式:
首先将其转换为promise,然后通过。然后()
方法收听它,并等待已解决的promise
可观察的。采取(1)
注意,对于toPromise
方法,不要忘记从rxjs操作符导入toPromise
,对于take
方法,也应该从rxjs导入take
方法
更新。角度版本>=6
从angular 6开始,要求rxjs>=6。在该函数中,现在可以导入像take
这样的运算符,并在.pipe()
方法中使用
我在这里找到了一个解决方案,它同时使用了
Angularfire2
和firebase原生API
我从你那里得到了这个解决方案
.ts
constructor(){
this.db=firebase.firestore();
}
异步登录WithGoogle():承诺{
试一试{
const response=等待this.afAuth.auth.signInWithRedirect(new firebase.auth.GoogleAuthProvider());
const result=wait this.afAuth.auth.getRedirectResult();
this.user=result.user;
const userId:string=result.user.uid;
const userProfile:AngularFirestoreDocument=this.fireStore.doc(`userProfile/${userId}`);
const res=wait this.db.collection(“userProfiles”)。其中(“email”,“data”).get();
如果(res.docs.length==0){
等待userProfile.set({
id:userId,
电子邮件:result.additionalUserInfo.profile.email,
creationTime:moment().format(),
lastsignentime:moment().format()格式
});
}否则{
等待userProfile.update({
lastsignentime:moment().format()格式
});
}
返回result.additionalUserInfo.profile.email;
}
捕捉(错误){
控制台日志(err);
}
}
您是否考虑过将可观察的
转换为只执行一次的承诺
?您也可以执行。在收到一个值后,采取(1)
强制订阅完成。我尝试过。但没有区别。请查看更新@Szarik@Sampath可能正在调用.complete()
onobserver
可以工作吗?ussubscribe()
获取数据后的对象这不工作[ts]属性“take”在类型“Observable”上不存在。
我已经像这样导入了它import{map,first,take}从'rxjs/operators';
你的typescript
和rxjs
版本是什么?只是好奇,试着使用这个(userProfiles$如有)。取(1)…
并检查它是否正常工作。这不是最好的解决方案,但我只是好奇。Promise方法根本不起作用。也没有错误。只是不要启动那个方法。这里也一样(userProfiles$和任何一样)。采取(1)
。不要启动那个方法。
async loginWithGoogle(): Promise<void> {
try {
const result = await this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
const userId: string = result.additionalUserInfo.profile.id;
const userProfile: AngularFirestoreDocument<UserProfile> = this.fireStore.doc(`userProfile/${userId}`);
const userProfiles: AngularFirestoreCollection<UserProfile> = this.fireStore.collection('userProfile/', ref => ref.where('email', '==', result.additionalUserInfo.profile.email));
const userProfiles$: Observable<UserProfile[]> = userProfiles.valueChanges();
userProfiles$.subscribe(async res => { //problem is here
if (res.length == 0) {
await userProfile.set({
id: userId,
email: result.additionalUserInfo.profile.email,
creationTime: moment().format(),
lastSignInTime: moment().format()
});
} else {
await userProfile.update({
lastSignInTime: moment().format()
});
}
});
}
catch (err) {
console.log(err);
}
}
userProfiles$.map(async res => {
if (res.length == 0) {
await userProfile.set({
id: userId, email: result.additionalUserInfo.profile.email,
creationTime: moment().format(),
lastSignInTime: moment().format()
});
}
}).toPromise();
"typescript": "2.4.2"
"rxjs": "5.5.2",
userProfiles$.toPromise().then((res) => {
if (res.length == 0) {
await userProfile.set({
id: userId, email: result.additionalUserInfo.profile.email,
creationTime: moment().format(),
lastSignInTime: moment().format()
});
}
}).catch(err => {
// handle error
});
userProfiles$.take(1).subscribe(async res => { //problem is here
if (res.length == 0) {
await userProfile.set({
id: userId,
email: result.additionalUserInfo.profile.email,
creationTime: moment().format(),
lastSignInTime: moment().format()
});
} else {
await userProfile.update({
lastSignInTime: moment().format()
});
}
});
// somewhere at the top of file
import { take } from 'rxjs/operators';
userProfiles$.pipe(take(1)).subscribe(async res => { //problem is here
if (res.length == 0) {
await userProfile.set({
id: userId,
email: result.additionalUserInfo.profile.email,
creationTime: moment().format(),
lastSignInTime: moment().format()
});
} else {
await userProfile.update({
lastSignInTime: moment().format()
});
}
});
get
get() returns firebase.firestore.QuerySnapshot
Executes the query and returns the results as a QuerySnapshot.
Returns
non-null firebase.firestore.QuerySnapshot A promise that will be resolved with the results of the query.
constructor() {
this.db = firebase.firestore();
}
async loginWithGoogle(): Promise<string> {
try {
const response = await this.afAuth.auth.signInWithRedirect(new firebase.auth.GoogleAuthProvider());
const result = await this.afAuth.auth.getRedirectResult();
this.user = result.user;
const userId: string = result.user.uid;
const userProfile: AngularFirestoreDocument<UserProfile> = this.fireStore.doc(`userProfile/${userId}`);
const res = await this.db.collection("userProfiles").where("email", "==", data).get();
if (res.docs.length === 0) {
await userProfile.set({
id: userId,
email: result.additionalUserInfo.profile.email,
creationTime: moment().format(),
lastSignInTime: moment().format()
});
} else {
await userProfile.update({
lastSignInTime: moment().format()
});
}
return result.additionalUserInfo.profile.email;
}
catch (err) {
console.log(err);
}
}