【问题标题】:How to wait for subscribe to finish Angular 5?如何等待订阅完成 Angular 5?
【发布时间】:2020-10-28 02:26:53
【问题描述】:

我正在开发一个 Angular 5 应用程序。我收到一个错误,因为我有一个在另一个函数完成之前执行的函数,因此得到一个空变量。我曾尝试将 .map 和 .subscribe 与 Observable 一起使用,但没有成功。代码如下:

loadData 是从我的 app.component 类调用的:

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

当该函数执行时,data.component 类中的另一个函数(dataService.getData)在初始化时被调用:

constructor(private dataService: DataService) {}

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

这是 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"]);
    }
    ...
}

问题是 sessionStorage["data"] 在 loadData() 完成之前为空,并且我多次收到此错误:

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

我知道如果我想等待订阅完成,我必须将需要等待的代码 (getData()) 放在订阅调用之后。但是需要等待的函数是从其他类调用的,那我怎么放在那里呢?

【问题讨论】:

    标签: angular rxjs angular5 angular-observable


    【解决方案1】:

    您错误地将代码放在订阅处理程序“之后”,您需要将其放在订阅处理程序的内部,但无论如何,

    您需要在这里使用某种主题,在这种特殊情况下可能是 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
                ...
            }
        }
    }
    

    那么您将订阅组件中的主题...

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

    【讨论】:

    • 谢谢!这解决了主要问题。但是仍然有一个错误。因为如上所述,data.service 类中的 getData() 函数也是从其他类调用的。所以,我有几个组件多次调用 getData() 函数。使用这些组件时,错误再次出现。我是否必须订阅所有使用 getData 函数的组件中的每个函数? (有许多)。或者我可以对 getData 函数做点什么,让它等待 loadData 函数完成吗?
    • 什么都不应该使用获取数据功能。任何对数据感兴趣的人都应该订阅它。
    猜你喜欢
    • 2019-03-24
    • 1970-01-01
    • 2021-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多