Mam usługę, która zwraca obserwowalny, który wysyła żądanie http do mojego serwera i pobiera dane. Chcę użyć tych danych, ale zawsze otrzymuję undefined
. Jaki jest problem?
Usługa :
@Injectable()
export class EventService {
constructor(private http: Http) { }
getEventList(): Observable<any>{
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.get("http://localhost:9999/events/get", options)
.map((res)=> res.json())
.catch((err)=> err)
}
}
Składnik:
@Component({...})
export class EventComponent {
myEvents: any;
constructor( private es: EventService ) { }
ngOnInit(){
this.es.getEventList()
.subscribe((response)=>{
this.myEvents = response;
});
console.log(this.myEvents); //This prints undefined!
}
}
Sprawdziłem, jak zwrócić odpowiedź z wywołania asynchronicznego? opublikuj, ale nie mogłem znaleźć rozwiązania
Odpowiedzi:
Powód:
Powodem jest
undefined
to, że wykonujesz operację asynchroniczną. Oznacza to, że ukończeniegetEventList
metody zajmie trochę czasu (w zależności głównie od szybkości sieci).Spójrzmy więc na wywołanie http.
Po wykonaniu („odpaleniu”) żądania http
subscribe
będziesz czekać na odpowiedź. Podczas oczekiwania javascript wykona wiersze poniżej tego kodu i jeśli napotka synchroniczne przypisania / operacje, wykona je natychmiast.Więc po zasubskrybowaniu
getEventList()
i oczekiwaniu na odpowiedź,console.log(this.myEvents);
linia zostanie wykonana natychmiast. A wartość tego jest
undefined
zanim odpowiedź nadejdzie z serwera (lub do czegokolwiek, co zainicjowałeś w pierwszej kolejności).Jest to podobne do zrobienia:
Rozwiązanie:
Więc zmieniając kod na:
wypisze odpowiedź ... po pewnym czasie.
Co powinieneś zrobić:
Z odpowiedzią może być wiele innych rzeczy niż tylko jej rejestrowanie; powinieneś wykonać wszystkie te operacje wewnątrz wywołania zwrotnego (wewnątrz
subscribe
funkcji), kiedy nadejdą dane.Inną rzeczą, o której warto wspomnieć, jest to, że jeśli pochodzisz z
Promise
tła,then
wywołanie zwrotne odpowiadasubscribe
obserwabli.Czego nie powinieneś robić:
Nie należy próbować zmieniać operacji asynchronicznej na operację synchronizacji (nie jest to możliwe). Jednym z powodów, dla których mamy operacje asynchroniczne, jest to, że nie zmuszamy użytkownika do czekania na zakończenie operacji, podczas gdy mogą wykonywać inne czynności w tym okresie. Załóżmy, że ukończenie jednej z operacji asynchronicznych zajmuje 3 minuty, a gdybyśmy nie mieli operacji asynchronicznych, interfejs zawiesiłby się na 3 minuty.
Sugerowane czytanie:
Pierwotny zasługa tej odpowiedzi to: Jak zwrócić odpowiedź z wywołania asynchronicznego?
Ale w wydaniu angular2 zostaliśmy wprowadzeni do maszynopisu i obserwabli, więc mam nadzieję, że ta odpowiedź obejmuje podstawy obsługi żądania asynchronicznego z obserwablami.
źródło
Wykonywanie wywołania http w angular / javascript jest operacją asynchroniczną. Więc kiedy wykonasz wywołanie http, przypisze nowy wątek, aby zakończyć to wywołanie i rozpocząć wykonywanie następnej linii z innym wątkiem. Dlatego otrzymujesz nieokreśloną wartość. więc wprowadź poniżej zmiany, aby rozwiązać ten problem
źródło
Możesz użyć asyncPipe, jeśli używasz myEvents tylko w szablonie.
Oto przykład z asyncPipe i Angular4 HttpClient przykład
źródło
Observables są leniwe, więc musisz subskrybować, aby uzyskać wartość. Zasubskrybowałeś go poprawnie w swoim kodzie, ale jednocześnie zarejestrowałeś dane wyjściowe poza blokiem „subskrybuj”. Dlatego jest „nieokreślony”.
Więc jeśli zarejestrujesz go w bloku subskrypcji, zarejestruje odpowiedź poprawnie.
źródło
Tutaj problem polega na tym, że inicjalizujesz
this.myEvents
wsubscribe()
którym jest blok asynchroniczny, podczas gdy robiszconsole.log()
po prostu pozasubscribe()
blokiem. Więcconsole.log()
wywołanie przedthis.myEvents
zostanie zainicjalizowane.Przenieś swój kod console.log () również do środka subscribe () i gotowe.
źródło
Wynik jest niezdefiniowany, ponieważ proces kątowy jest asynchroniczny. możesz spróbować jak poniżej:
źródło
Upewnij się również, że mapujesz swoją odpowiedź na dane wyjściowe JSON. W przeciwnym razie zwróci zwykły tekst. Robisz to tak:
źródło
Niezdefiniowane, ponieważ wartość tutaj jest rejestrowana, zanim jakiekolwiek dane z usługi zostaną ustawione na podstawie powyższego wywołania usługi subskrypcji. Musisz więc poczekać, aż wywołanie Ajax zakończy się i ustawić dane z danych odpowiedzi.
Tutaj zrób dziennik konsoli w metodzie subscribe, która będzie logować, gdy dane są ustawione w zmiennej myEvents.
źródło
Możesz po prostu wypróbować tę metodę-
źródło