如何从角度中的Observable / http / async调用返回响应?

如何从角度中的Observable / http / async调用返回响应?

我有一个服务,它返回一个observable,它向我的服务器发送一个http请求并获取数据。我想使用这些数据,但我总是得到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!
  }}


神不在的星期二
浏览 888回答 6
6回答

蓝山帝景

原因:原因在于undefined您正在进行异步操作。这意味着完成该getEventList方法需要一些时间(主要取决于您的网络速度)。所以让我们来看看http调用。this.es.getEventList()实际制作(“开火”)后,您的http请求subscribe将等待响应。在等待时,javascript将执行此代码下面的行,如果遇到同步赋值/操作,它将立即执行它们。所以在订阅getEventList()并等待响应后,console.log(this.myEvents);线将立即执行。并且它的值是undefined在响应从服务器到达之前(或者在您首先初始化它的任何内容)。它类似于:ngOnInit(){ &nbsp;&nbsp;&nbsp;&nbsp;setTimeout(()=>{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.myEvents&nbsp;=&nbsp;response; &nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;5000); &nbsp;&nbsp;&nbsp;&nbsp;console.log(this.myEvents);&nbsp;//This&nbsp;prints&nbsp;undefined!}解:那么我们如何克服这个问题呢?我们将使用回调函数,即subscribe方法。因为当数据从服务器到达时,它将subscribe在响应中。所以将代码更改为:this.es.getEventList() &nbsp;&nbsp;&nbsp;&nbsp;.subscribe((response)=>{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.myEvents&nbsp;=&nbsp;response; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log(this.myEvents);&nbsp;//<--&nbsp;not&nbsp;undefined&nbsp;anymore &nbsp;&nbsp;&nbsp;&nbsp;});将在一段时间后打印回复。你应该做什么:除了记录之外,您的响应可能还有很多事情要做;&nbsp;subscribe当数据到达时,你应该在回调内部(函数内部)执行所有这些操作。另外要提到的是,如果你来自Promise背景,则then回调对应于subscribeobservable。你不该做的事:您不应该尝试将异步操作更改为同步操作(不是您可以)。我们具有异步操作的原因之一是不让用户等待操作完成,而他们可以在该时间段内执行其他操作。假设您的一个异步操作需要3分钟才能完成,如果我们没有异步操作,则接口将冻结3分钟。推荐阅读:这个答案的最初归功于:如何从异步调用返回响应?但是对于angular2版本,我们被引入了typescript和observables,所以这个答案希望涵盖处理带有observables的异步请求的基础知识。

宝慕林4294392

在angular / javascript中进行http调用是异步操作。因此,当您进行http调用时,它将分配新线程来完成此调用并开始执行下一行与另一个线程。这就是为什么你得到未定义的价值。所以在下面进行更改以解决此问题this.es.getEventList()&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.subscribe((response)=>{&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.myEvents&nbsp;=&nbsp;response;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log(this.myEvents);&nbsp;//<-this&nbsp;become&nbsp;synchronous&nbsp;now&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;});

DIEA

这里的问题是,当你刚刚进行阻塞时,你正在初始化this.myEvents为subscribe()异步块。因此在被初始化之前被调用。console.log()subscribe()console.log()this.myEvents请将您的console.log()代码移到subscribe()内部,然后就完成了。ngOnInit(){ &nbsp;&nbsp;&nbsp;&nbsp;this.es.getEventList() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.subscribe((response)=>{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.myEvents&nbsp;=&nbsp;response; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log(this.myEvents); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;}

慕姐8265434

Observable是懒惰的,所以你必须订阅才能获得价值。您在代码中正确订阅了它,但同时将输出记录在'subscribe'块之外。这就是“未定义”的原因。ngOnInit()&nbsp;{ &nbsp;&nbsp;this.es.getEventList() &nbsp;&nbsp;&nbsp;&nbsp;.subscribe((response)&nbsp;=>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.myEvents&nbsp;=&nbsp;response; &nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;console.log(this.myEvents);&nbsp;//Outside&nbsp;the&nbsp;subscribe&nbsp;block&nbsp;'Undefined'}因此,如果您将其记录在订阅块中,那么它将正确记录响应。ngOnInit(){ &nbsp;&nbsp;this.es.getEventList() &nbsp;&nbsp;&nbsp;&nbsp;.subscribe((response)=>{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.myEvents&nbsp;=&nbsp;response; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.log(this.myEvents);&nbsp;//Inside&nbsp;the&nbsp;subscribe&nbsp;block&nbsp;'http&nbsp;response' &nbsp;&nbsp;&nbsp;&nbsp;});}

炎炎设计

结果是未定义的,因为角度处理异步。你可以尝试如下:async&nbsp;ngOnInit(){ &nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;res&nbsp;=&nbsp;await&nbsp;this.es.getEventList(); &nbsp;&nbsp;&nbsp;&nbsp;console.log(JSON.stringify(res));}

慕少森

还要确保将响应映射到json输出。否则它将返回纯文本。你这样做是这样的: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)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map((res)=>{ return res.json();}) <!-- add call to json here&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .catch((err)=>{return err;})}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript