简体   繁体   English

如何等待订阅完成 Angular 5?

[英]How to wait for subscribe to finish Angular 5?

I am working on an Angular 5 app.我正在开发一个 Angular 5 应用程序。 I get an error because I have a function that executes before another function is done, hence getting a null variable.我收到一个错误,因为我有一个函数在另一个函数完成之前执行,因此得到一个空变量。 I have tried to use .map and .subscribe with Observable, but didn't succeed.我曾尝试将 .map 和 .subscribe 与 Observable 一起使用,但没有成功。 Here is the code:这是代码:

loadData is called from my app.component class :从我的app.component 类调用 loadData :

ngOnInit() {
    this.dataService.loadData(sessionStorage.getItem(...);
}

While that function executes, another function from data.component class (dataService.getData) is called on initialization:当该函数执行时,来自data.component 类(dataService.getData) 的另一个函数在初始化时被调用:

constructor(private dataService: DataService) {}

ngOnInit() {
    this.dataTxt = this.dataService.getData(...);
}

Here is the data.service class:这是data.service 类:

loadData(... : void) {
    if (sessionStorage["data"] == null {
        this.http.request(...)
        .map((response: Response) => response.json()).subscribe(data => {
            ...
            sessionStorage.setItem("data", JSON.stringify(this.data));
            ...
        }
    }
}

getData(... : string){
    if (this.data == null) {
        this.data = JSON.parse(sessionStorage["data"]);
    }
    ...
}

The problem is that sessionStorage["data"] is null until loadData() is done and I get this error a few times:问题是sessionStorage["data"]在 loadData() 完成之前为空,我多次收到此错误:

ERROR SyntaxError: Unexpected token u in JSON at position 0
    at JSON.parse (<anonymous>)

I understand that if I want to wait for subscribe to finish, I have to put the code that need to wait (getData()) just after the subscribe call.我知道如果我想等待 subscribe 完成,我必须在 subscribe 调用之后放置需要等待的代码 (getData())。 But the function that needs to wait is called from other classes so how do I put it there?但是需要等待的函数是从其他类调用的,那么我如何把它放在那里呢?

you're mistaken that you'd put your code "after" the subscribe handler, you'd need to put it INSIDE of the subscribe handler, but regardless,您误以为您将代码放在订阅处理程序的“之后”,您需要将其放在订阅处理程序的内部,但无论如何,

you need to use a subject of some kind here, probably a ReplaySubject in this particular case...您需要在这里使用某种主题,在这种特殊情况下可能是ReplaySubject ...

private dataSource = new ReplaySubject(1) // create a private subject
data$ = this.dataSource.asObservable() // and a public observable

loadData(... : void) {
    if (sessionStorage["data"] == null {
        this.http.request(...)
        .map((response: Response) => response.json()).subscribe(data => {
            ...
            sessionStorage.setItem("data", JSON.stringify(this.data));
            this.dataSource.next(data) // set the data in the subject
            ...
        }
    }
}

then you'd subscribe to the subject in your component...然后您将订阅组件中的主题...

ngOnInit() {
    this.dataService.data$.pipe(first()) // avoid memory leak.
      .subscribe(data => this.dataTxt = data);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM