首先几十年没有编写代码(前Java开发人员),所以只是熟悉Angular 4作为一种爱好,但我缺乏一个基本的理解。我搜索了使用observable处理数据检索延迟,但没有找到任何相关结果。希望有人在这里可以帮助和解释。它围绕以下TypeScript代码展开(请参阅内联注释):
RemoteDataService
export class RemoteDataService {
private headers = new Headers({ 'Content-Type': 'application/json' });
constructor(private http: Http) { }
public getData(url) {
return this.http.get(url)
.map(
(response: Response) => {
const data = response.json();
return data;
}
)
}
}
ArticleService
export class ArticleService implements OnInit {
_articles: Article[];
constructor(private _remoteDataService: RemoteDataService) {
this.onGet();
console.log(JSON.stringify(this._articles)) **//<- this._articles is null**
setTimeout(()=> console.log(JSON.stringify(this._articles + "////")), 3000)
} **//<- but if I wait 3 seconds this._articles is set to data elements**
public onGet() {
this._remoteDataService.getData('./assets/articles.json')
.subscribe(
(articles: any[]) => {
this._articles = articles,
console.log(this._articles) **//<- this_.articles is set**
},
(error) => console.log(error))
//console.log(this._articles) **//<- if I uncomment this_.articles is null, huh?**
}
}
输出:
article.service.ts:34“undefined ////”
article.service.ts:46(20)[{...},{...},{...},{...},{...},{...},{...},{...},{...}, {...},?&gt; {...},{...},{...},{...},{...},{...},{...},{...},{...},{...}]
article.service.ts:35“[object Object],[object Object],[object Object],[object&gt; Object],[object Object],[object Object],[object Object],[object Object],[object&gt; Object],[object Object],[object Object],[object Object],[object Object],[object&gt; Object],[object Object],[object Object],[object Object ],[object Object],[object&gt; Object],[object Object] ////“
我的问题是:
1)为什么onGet()
方法this._articles
会被设置为空?
2)数据延迟通常是如何处理的,因为调用服务的组件崩溃了,因为尚未设置文章?
答案 0 :(得分:0)
1)您对服务的调用正在进行异步,这意味着调用是在另一个线程中进行的,但onGet()
继续执行。在控制台中记录它时,尚未设置this._articles。
2)哇,这是一个很大的问题,答案在很大程度上取决于你想要完成的事情。首先,使用setTimeout()是不好的做法。您需要以不使用任何数据的方式设计组件。如果您的模板正在破坏,safe navigation operator可能会派上用场。如果您提供更多详细信息,我将很乐意为您提供帮助。
答案 1 :(得分:0)
我想我明白了。 。 。抱歉打扰所有人。
我把它放在我的文章服务
中articleHasChanged = new Subject<Article[]>();
这将此代码添加到我的组件
private _articleSubscription: Subscription;
this._articleSubscription = this._articleService.articleHasChanged.subscribe({
next: (articles) => {
console.log("Time to get the article");
this._articleService.getArticleByID(this.id);
console.log(this.diagnostic)
}
}
)
这似乎有效
答案 2 :(得分:0)
您需要阅读有关Angular订阅和observable的更多信息。因为这些与您认为它的工作方式不同。这可能是good article for that但您应该搜索。我认为这是official API documentation
这很容易理解。每当您在应用中提出请求时。该应用程序不必等到请求完成。这与浏览器的工作方式非常相似。您在浏览器中输入一个URL并在页面加载时执行其他操作,然后当您看到浏览器已完成加载后,您将继续并通过该页面使用。使用this.http.get(url)
时,浏览器会处理当前应用范围之外的请求。因此,当浏览器发出请求并等待响应时,将继续执行以下代码块。因此,当执行任何其他代码时,请求尚未完成加载,而请求可能需要几秒钟才能完成加载。
当你使用return this.http.get(url).map()
时 - 你正在返回一个observable,它在调用请求后立即返回 - 当服务器没有响应时它仍在加载。
.subscribe(
(articles: any[]) => {
this._articles = articles,
console.log(this._articles) **//<- this_.articles is set**
},
(error) => console.log(error))
这部分代码订阅了observable。因此,当请求完成加载时,subscribe()
内的任何代码都会被执行,具体取决于请求是否成功。 public onGet() {}
范围内的所有代码现在将在.subscribe()
之后执行。这只会在请求加载完成后执行。
您永远不会知道请求加载需要多长时间,因此使用setTimeout()
将无用。因此,最好让计算机在请求完成加载时通知您,当您使用Observables时