我有以下返回observer的方法,但它被调用两次:
public getClassesAndSubjects(school: number, whenDate: string): Observable<ClassesAndSubjects[]> {
console.log('1');
const observable = this.classService.GetClassesAndSubjects(school, whenDate);
console.log("2");
observable.subscribe(data => {
if (!data.hasOwnProperty('errors')) {
this.classesSubjects = data;
}
}, error => {
console.log("ERROR loading GetClassesAndSubjects: " + error);
});
console.log("3");
return observable;
}
我的意思是一行const observable = this.classService.GetClassesAndSubjects(school, whenDate);
被调用两次并向服务器发送两次请求。
将其称为:
this.classInstance.getClassesAndSubjects(school, date).subscribe(value => {
// TODO
});
答案 0 :(得分:3)
这种情况正在发生,因为您订阅了两次observable,并且每次他们订阅时都会执行observable。
改变这个:
observable.subscribe(data => {
if (!data.hasOwnProperty('errors')) {
this.classesSubjects = data;
}
}, error => {
console.log("ERROR loading GetClassesAndSubjects: " + error);
});
到此:
observable.do(data => {
if (!data.hasOwnProperty('errors')) {
this.classesSubjects = data;
}
});
这样您就可以在您的信息流中添加一个操作员,直到您在回程中订阅它为止。
答案 1 :(得分:1)
与Promise不同,Observable的函数在订阅时调用,而不是在创建时调用。 Observable的每个subscription
都会导致Observable函数再次运行。
如果您想与多个订阅者共享一个Observable的发射,请使用share()
。否则,如果您只想在不订阅Observable的情况下标记排放功能,则可以使用do()
(或tap
用于RxJS 5 +)。
答案 2 :(得分:1)
您遇到了麻烦,因为您在两个地方订阅了相同的方法。
// Your code that is subscribing to the events in two different places, which is why it is called twice.
/*public getClassesAndSubjects(school: number, whenDate: string): Observable<ClassesAndSubjects[]> {
console.log('1');
const observable = this.classService.GetClassesAndSubjects(school, whenDate);
console.log("2");
observable.subscribe(data => {
if (!data.hasOwnProperty('errors')) {
this.classesSubjects = data;
}
}, error => {
console.log("ERROR loading GetClassesAndSubjects: " + error);
});
console.log("3");
return observable;
}*/
import { tap, catchError } from 'rxjs/operators';
import { Observable } from 'rxjs/Observable';
public getClassesAndSubjects(school: number, whenDate: string): Observable<ClassesAndSubjects[]> {
return this.classService.GetClassesAndSubjects(school, whenDate)
.pipe(
tap(data => this.classesSubjects = !data.hasOwnProperty('errors') ? data : this.classesSubjects),
catchError(err => {
console.log("ERROR loading GetClassesAndSubjects: " + error);
return Observable.throw(err);
})
);
}