Ich habe einen Dienst, der eine Observable zurückgibt, die eine http-Anfrage an meinen Server sendet und die Daten abruft. Ich möchte diese Daten verwenden, bekomme sie aber immer wieder undefined
. Was ist das Problem?
Service :
@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)
}
}
Komponente:
@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!
}
}
Ich habe überprüft, wie ich die Antwort von einem asynchronen Anruf zurückgeben kann. Post konnte aber keine Lösung finden
Antworten:
Grund:
Der Grund dafür
undefined
ist, dass Sie eine asynchrone Operation ausführen. Das bedeutet, dass es einige Zeit dauern wird, bis diegetEventList
Methode abgeschlossen ist (hauptsächlich abhängig von Ihrer Netzwerkgeschwindigkeit).Schauen wir uns also den http-Aufruf an.
Nachdem Sie Ihre http-Anfrage mit Ihnen tatsächlich gestellt ("ausgelöst")
subscribe
haben, warten Sie auf die Antwort. Während des Wartens führt Javascript die Zeilen unter diesem Code aus und führt sie sofort aus, wenn es auf synchrone Zuweisungen / Operationen stößt.Nachdem Sie die abonniert
getEventList()
und auf die Antwort gewartet haben,console.log(this.myEvents);
Zeile wird sofort ausgeführt. Und der Wert davon ist,
undefined
bevor die Antwort vom Server eintrifft (oder zu dem, was Sie zuerst initialisiert haben).Es ist ähnlich wie:
Lösung:
Ändern Sie den Code also in:
druckt die Antwort .. nach einiger Zeit.
Was du machen solltest:
Es kann viele andere Dinge mit Ihrer Antwort zu tun haben, als sie nur zu protokollieren. Sie sollten alle diese Vorgänge innerhalb des Rückrufs (innerhalb der
subscribe
Funktion) ausführen , wenn die Daten eintreffen.Eine andere Sache zu erwähnen ist, dass, wenn Sie aus einem
Promise
Hintergrund kommen, derthen
Rückrufsubscribe
mit Observablen entspricht.Was Sie nicht tun sollten:
Sie sollten nicht versuchen, einen asynchronen Vorgang in einen Synchronisierungsvorgang umzuwandeln (nicht, dass Sie dies können). Einer der Gründe für asynchrone Vorgänge besteht darin, dass der Benutzer nicht auf den Abschluss eines Vorgangs warten muss, während er in diesem Zeitraum andere Aufgaben ausführen kann. Angenommen, einer Ihrer asynchronen Vorgänge dauert 3 Minuten. Wenn wir die asynchronen Vorgänge nicht hätten, würde die Schnittstelle 3 Minuten lang einfrieren.
Vorgeschlagene Literatur:
Die ursprüngliche Gutschrift für diese Antwort lautet: Wie kann ich die Antwort von einem asynchronen Anruf zurückgeben?
Mit der Version angle2 wurden wir jedoch mit Typoskript und Observablen vertraut gemacht, sodass diese Antwort hoffentlich die Grundlagen der Behandlung einer asynchronen Anforderung mit Observablen abdeckt.
quelle
Ein http-Aufruf in Angular / Javascript ist eine asynchrone Operation. Wenn Sie also einen http-Aufruf durchführen, wird ein neuer Thread zugewiesen, um diesen Aufruf zu beenden und die Ausführung in der nächsten Zeile mit einem anderen Thread zu starten. Deshalb erhalten Sie einen undefinierten Wert. Nehmen Sie daher die folgenden Änderungen vor, um dies zu beheben
quelle
Sie können asyncPipe verwenden, wenn Sie myEvents nur in Vorlagen verwenden.
Hier Beispiel mit asyncPipe und Angular4 HttpClient Beispiel
quelle
Observables sind faul, daher müssen Sie sich anmelden, um den Wert zu erhalten. Sie haben es ordnungsgemäß in Ihrem Code abonniert, aber gleichzeitig die Ausgabe außerhalb des Blocks "Abonnieren" protokolliert. Deshalb ist es "undefiniert".
Wenn Sie es also im Abonnementblock protokollieren, wird die Antwort ordnungsgemäß protokolliert.
quelle
Hier ist das Problem, Sie initialisieren
this.myEvents
insubscribe()
dem ein asynchroner Block , während Sie tun ,console.log()
gerade aus demsubscribe()
Block. Soconsole.log()
genannt , bevor manthis.myEvents
wird initialisiert.Bitte verschieben Sie Ihren console.log () - Code ebenfalls in subscribe () und Sie sind fertig.
quelle
Das Ergebnis ist undefiniert, da der Winkelprozess asynchron ist. Sie können wie folgt versuchen:
quelle
Stellen Sie außerdem sicher, dass Sie Ihre Antwort einer JSON-Ausgabe zuordnen. Andernfalls wird Klartext zurückgegeben. Du machst es so:
quelle
Nicht definiert, da der Wert hier protokolliert wird, bevor Daten vom Dienst aus dem oben genannten Abonnementdienstaufruf festgelegt werden. Sie müssen also warten, bis der Ajax-Aufruf beendet ist, und die Daten aus den Antwortdaten festlegen.
Erstellen Sie hier das Konsolenprotokoll innerhalb der Subscribe-Methode, mit der das Protokoll erstellt wird, wenn die Daten in der Variablen myEvents festgelegt werden.
quelle
Sie können diese Methode einfach ausprobieren.
quelle