我有返回一个observable的服务,该服务向我的服务器发出一个http请求并获取数据。我想使用这些数据,但是我总是最终得到undefined。有什么问题?
undefined
服务内容 :
@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) } }
零件:
@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! } }
原因:
这undefined是因为您正在执行异步操作。意味着完成该getEventList方法将需要一些时间(主要取决于您的网络速度)。
getEventList
因此,让我们看一下http调用。
this.es.getEventList()
实际发出(“触发”)请求后,与您的http请求subscribe将 等待 响应。等待期间,javascript将执行此代码下面的行,如果遇到同步分配/操作,它将立即执行它们。
subscribe
因此,在订阅getEventList()并等待响应后,
getEventList()
console.log(this.myEvents);
行将立即执行。而且它的值是undefined在响应从服务器到达之前(或首先初始化的内容)。
类似于执行以下操作:
ngOnInit(){ setTimeout(()=>{ this.myEvents = response; }, 5000); console.log(this.myEvents); //This prints undefined! }
解:
那么我们如何克服这个问题呢?我们将使用该subscribe方法的回调函数。因为当数据从服务器到达时,它将subscribe在响应中。
因此,将代码更改为:
this.es.getEventList() .subscribe((response)=>{ this.myEvents = response; console.log(this.myEvents); //<-- not undefined anymore });
会在一段时间后打印响应。
您应该做什么:
除了记录响应之外,您的响应可能还有很多事情要做。您应该subscribe在数据到达时在回调函数(在函数内部)内执行所有这些操作。
要提到的另一件事是,如果您来自Promise后台,则then回调subscribe与可观察对象相对应。
Promise
then
您不应该做的事情:
您不应该尝试将异步操作更改为同步操作(并非可以)。我们进行异步操作的原因之一是,在该时间段内用户可以执行其他操作时,不要让用户等待操作完成。假设您的一个异步操作需要3分钟才能完成,如果我们没有异步操作,该接口将冻结3分钟。