Angular2 - перемещение после завершения наблюдения
У меня есть http
наблюдаемый, например, в моем UserService
:
logout() {
return this.http.delete(this.baseUrl + url, {
headers: this.headers()
}).map((res: IResponse) => {
var json = res.json();
json.headers = res.headers;
return json;
}).subscribe((response) => {
//DO SOMETHING, THEN ----
return res;
});
}
Я создал наблюдаемый и создал подписку (response
), которая является возвращаемым значением успеха.
Теперь, в моем компоненте, я хочу вызвать UserService.logout()
и THEN перейти к новому маршруту:
logout() {
this.userService.logout();
this.router.navigate(['LandingPage']);
}
Очевидно, что это может произойти асинхронно, и я могу закончить навигацию до выхода из системы.
Используя promises, я мог бы сделать что-то вроде этого:
this.userService.logout().then(() => {
this.router.navigate(['LandingPage']);
});
Как я могу сделать то же самое с наблюдаемыми? В моем классе UserService
я хочу создать наблюдаемый, подписаться на него, сделать некоторые вещи с успехом или ошибкой, ТОГДА перейти от моего компонента представления.
Ответы
Ответ 1
Фактически вы можете сделать метод logout
вернуть обещание и использовать его как обычно. Он не должен быть наблюдаемым:
logout() {
return new Promise((resolve, reject) => {
this.http.delete(this.baseUrl + url, { headers: this.headers() })
.map((res: IResponse) => {
var json = res.json();
json.headers = res.headers;
return json;
})
.subscribe(data => {
//DO SOMETHING, THEN ----
resolve(data);
}, error => reject(error));
});
}
logout() {
this.userService.logout().then(response => this.router.navigate(['LandingPage']))
}
Ответ 2
Наблюдаемый объект имеет метод, наконец, попробуйте.
Не забывайте сначала импортировать:
import 'rxjs/operators/finally';
Ваш выход() будет выглядеть следующим образом:
logout() {
return this.http.delete(this.baseUrl + url, { headers: this.headers() })
.map(res => res.json())
.finally(() => this.router.navigate(['LandingPage']))
.subscribe((response) => {
//DO SOMETHING, THEN ----
});
}
Если вы действительно хотели использовать обещание:
import 'rxjs/add/operator/toPromise';
logout() {
return this.http.delete(this.baseUrl + url, { headers: this.headers() })
.map(res => res.json());
в компоненте .ts
var aPromise = this.userService.logout().toPromise();
aPromise.then(() => {
this.router.navigate(['LandingPage']);
});
Ответ 3
Вы не можете дождаться завершения Observable
, потому что его поток может продолжаться бесконечно. Но вы можете вызвать router.navigate
внутри метода subscribe
:
logout() {
return this.http.delete(this.baseUrl + url, { headers: this.headers() })
.map((res: IResponse) => res.json())
.subscribe((response) => {
//DO SOMETHING, THEN ----
this.router.navigate(['LandingPage']);
});
}
Если этого недостаточно, subscribe
возвращает Subscription
, метод unsubscribe
останавливает ожидание данных Observable
. Поэтому, если вам нужно, вы можете подождать период ожидания и вызвать unsubscribe
.
Ответ 4
Выход из системы должен вернуть Observable, а не подписку.
Например:
logout(): Observable<T> {
return this.http.delete(this.baseUrl + url, {
headers: this.headers()
}).map((res: IResponse) => {
var json = res.json();
json.headers = res.headers;
return json;
})
.catch((err)=>Observable.empty()) // return empty if error
.share(); // to ensure that no duplicate http calls can occur
}
//in component:
this.service.logout()
.do(()=>this.router.navigate(['LandingPage']);)//do stuff
.subscribe((res:any)=>{});
//or with template async pipe:
public result$ = Observable<T>;
result$ = this.service.logout()
.do(()=>//do stuff);
//in template:
{{(result$ | async)?.id}}
or simply
{{result$ | async}}
// P.s. do not forget about unsubscribe(), thats why I prefer to use async (since that the Async pipe job.)