【问题标题】:handling data retrieval latency angular处理数据检索延迟角
【发布时间】:2017-08-23 21:38:35
【问题描述】:

首先,十多年来没有编码(前 Java 开发人员),所以只是将熟悉 Angular 4 作为一种爱好,但我缺乏基本的了解。我搜索了使用 observables 处理数据检索延迟,但没有返回任何相关结果。希望这里有人可以帮助和解释。它围绕以下 TypeScript 代码展开(也请参见内联 cmets):

远程数据服务

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;
    }
  )
 }
}

文章服务

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 "未定义////"

article.service.ts:46 (20) [{...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {...}, {…}, ?>{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

article.service.ts:35 "[对象对象],[对象对象],[对象对象],[对象>对象],[对象对象],[对象对象],[对象对象],[对象对象] ],[对象>对象],[对象对象],[对象对象],[对象对象],[对象对象],[对象>对象],[对象对象],[对象对象],[对象对象],[对象对象],[对象>对象],[对象对象]////"

我的问题是

1) 为什么在onGet() 方法中this._articles 从被设置为null?

2) 通常如何处理数据延迟,因为我调用服务的组件由于文章尚未设置而崩溃?

【问题讨论】:

    标签: angular http observable latency subscribe


    【解决方案1】:

    1) 您正在对服务进行的调用异步发生,这意味着调用是在另一个线程中进行的,但onGet() 继续执行。 this._articles 在控制台登录时尚未设置。

    2) 唷,这是个大问题,答案很大程度上取决于您要完成的工作。一方面,使用 setTimeout() 是不好的做法。您需要以这样一种方式设计您的组件,使它们可以在没有任何数据的情况下工作。如果是您的模板出现问题,safe navigation operator 可能会派上用场。如果您提供更多详细信息,我很乐意提供帮助。

    【讨论】:

    • setTimeout() 函数仅用于测试目的。我得到了异步的东西,我不明白为什么它从被设置为空。 (代码中的最后一条注释)
    • 这是因为代码没有按照编写的顺序执行。 subscribe 函数被调用,但是console.log 是紧接着调用的,也就是调用结束之前。
    • 谢谢,我得到了整个指令序列的东西,但是我仍然不明白为什么控制台打印出 this_.articles 作为一个可行的对象,然后立即打印出 this._articles 为空。在我看来,每次都会打印 null ,然后在超时时最终会打印该值。我已经继续前进,现在解决了一个新问题,但这对我来说仍然很模糊。
    • 这需要一些时间来适应。只需阅读几篇文章,它就会有所帮助。附注:在组件构造函数中做的越少越好。您应该改为在 ngOnInit() 中完成工作。
    【解决方案2】:

    我想我明白了。 . .不好意思打扰大家了。

    我把它放在我的文章服务中

    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)
      }
    }
    )
    

    这似乎有效

    【讨论】:

      【解决方案3】:

      您需要阅读有关 Angular 订阅和可观察对象的更多信息。因为这些工作方式与您认为的工作方式不同。这可能是good article for that,但您应该搜索。我想这是official API documentation

      这很容易理解。每当您在应用程序中提出请求时。应用程序不必等到请求完成。这与您的浏览器的工作方式非常相似。您在浏览器中输入一个 url 并在页面加载时执行其他操作,然后当您看到浏览器已完成加载时,您将继续并通过页面使用。当您使用 this.http.get(url) 时,浏览器会处理您当前应用范围之外的请求。因此,当浏览器发出请求并等待响应时,以下代码块将继续执行。因此,当执行任何其他代码时,请求尚未完成加载,这发生得非常快,而请求可能需要几秒钟才能完成加载。

      当您使用 return this.http.get(url).map() 时 - 您将返回一个可观察对象,该可观察对象在请求被调用后立即返回 - 当服务器仍在加载时没有响应。

      .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 的时间

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-08
        • 2016-03-09
        • 2014-02-01
        • 2021-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多