如何在Angular中从Observable / http / async调用中返回响应?

2024-04-25 23:46:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个服务,它返回一个observate,它向我的服务器发出一个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!
  }
}

Tags: jsonhttpnewanyexportprivatethisclass
3条回答

在angular/javascript中进行http调用是异步操作。 因此,当您进行http调用时,它将分配新线程来完成此调用,并用另一个线程在下一行开始执行。 这就是为什么你得到了未定义的价值。 所以做下面的修改来解决这个问题

this.es.getEventList()  
      .subscribe((response)=>{  
       this.myEvents = response;  
        console.log(this.myEvents); //<-this become synchronous now  
    });

如果只在模板中使用myEvents,则可以使用asyncPype

下面是asyncPype和Angular4 HttpClienthttps://stackblitz.com/edit/angular-rhioqt?file=app%2Fevent.service.ts的示例

原因:

之所以是undefined,是因为您正在进行异步操作。这意味着完成getEventList方法需要一些时间(主要取决于网络速度)。

所以让我们看看http调用。

this.es.getEventList()

使用subscribe发出http请求(“fire”)后,您将等待响应。在等待时,javascript将执行下面的代码行,如果遇到同步分配/操作,它将立即执行它们。

所以在订阅getEventList()并等待响应之后

console.log(this.myEvents);

行将立即执行。它的值是undefined,在响应从服务器到达之前(或者在第一时间初始化它的任何内容)。

它类似于:

ngOnInit(){
    setTimeout(()=>{
        this.myEvents = response;
    }, 5000);

    console.log(this.myEvents); //This prints undefined!
}


解决方案:

So how do we overcome this problem? We will use the callback function which is the subscribe method. Because when the data arrives from the server it'll be inside the subscribe with the response.

因此,将代码更改为:

this.es.getEventList()
    .subscribe((response)=>{
        this.myEvents = response;
        console.log(this.myEvents); //<-- not undefined anymore
    });

将打印响应。。过了一段时间。


你应该做什么:

除了记录响应之外,可能还有很多事情要做;当数据到达时,您应该在回调函数(在subscribe函数内部)中执行所有这些操作。

另一件需要提及的事情是,如果您来自Promise背景,那么then回调对应于subscribe可观察。


不应该做的事:

您不应该尝试将异步操作更改为同步操作(这不是您可以做到的)。我们使用异步操作的原因之一是,当用户可以在该时间段内执行其他操作时,不会让用户等待操作完成。假设一个异步操作需要3分钟才能完成,如果没有异步操作,接口将冻结3分钟。


建议阅读:

这个答案最初的功劳是:How do I return the response from an asynchronous call?

但是在angular2版本中,我们被引入了typescript和observates,所以这个答案有望涵盖使用observates处理异步请求的基础知识。

相关问题 更多 >