处理数据检索延迟角度

时间:2017-08-23 21:38:35

标签: angular http observable latency subscribe

首先几十年没有编写代码(前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)数据延迟通常是如何处理的,因为调用服务的组件崩溃了,因为尚未设置文章?

3 个答案:

答案 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时