如何间隔发出HTTP请求?

托尼·克罗格

我对angular和rxjs很陌生。我正在尝试创建一个angular2应用程序,该应用程序从静态服务的文本文件(位于服务器本地)中获取一些数据,我想在固定时间使用Angular2的http提供程序和rxjs的映射来检索并映射到Datamodel interval(5000)反映对提供的txt文件的任何更改。

有了rxjs 4.x,我知道您可以Observable.interval(5000)用来完成这项工作,但是rxjs 5中似乎并不存在。我的解决方法当前使用刷新整个应用程序来<meta http-equiv="refresh" content="5" >重新加载整个页面,从而重新加载数据。

因此,我真正想要的是某种与可观察对象一起执行此操作的方法,也许可以检查是否发生了任何更改。或只是重新加载数据。

任何帮助或其他/更好的方式将不胜感激。

到目前为止,我有:

@Injectable()
export class DataService {

    constructor(private http:Http){}

    getData(url) {
        return this.http.get(url)
            .map(res => {
                return res.text();
            })
            .map(res => {
                return res.split("\n");
            })
            .map(res => {
                var dataModels: DataModel[] = [];
                res.forEach(str => {
                    var s = str.split(",");
                    if(s[0] !== "") {
                        dataModels.push(new DataModel(s[0], parseInt(s[1]), parseInt(s[2])));
                    }
                });
                return dataModels;
            })
    }
}

@Component({
selector: 'my-app',
template: `Some html to display the data`,
providers: [DataService],
export class AppComponent {

data:DataModel[];

constructor(dataService:DataService) {}

ngOnInit() {
    this.dataService.getData('url').subscribe(
        res => {
            this.data= res;

        },
        err => console.log(err),
        () => console.log("Data received")
        );
    }
}

依赖项:package.json

"dependencies": {
  "angular2": "^2.0.0-beta.3",
  "bootstrap": "^4.0.0-alpha.2",
  "es6-promise": "^3.0.2",
  "es6-shim": "^0.33.13",
  "jquery": "^2.2.0",
  "reflect-metadata": "^0.1.2",
  "rxjs": "^5.0.0-beta.0",
  "systemjs": "^0.19.20",
  "zone.js": "^0.5.11"
},
"devDependencies": {
  "typescript": "^1.7.5"
}

index.html导入:

<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>

<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>
扎克·德罗斯

正如@Adam和@Ploppy提到的那样, 不建议使用 Observable.interval(),而 不是创建此类可观察对象的首选方法。首选的方法是通过IntervalObservable或TimerObservable。[当前在打字稿2.5.2,rxjs 5.4.3,Angular 4.0.0中]

我想在此答案中添加一些用法,以说明我在Angular 2框架中找到了实现此目标的最佳方法。

首先是您的服务(通过'ng g service MyExample“命令在angular cli中创建)。假设该服务是RESTful的(http get request返回一个json):

my-example.service.ts

import { Injectable } from '@angular/core';
import { Http, Response} from "@angular/http";
import { MyDataModel } from "./my-data-model";
import { Observable } from "rxjs";
import 'rxjs/Rx';

@Injectable()
export class MyExampleService {
  private url = 'http://localhost:3000'; // full uri of the service to consume here

  constructor(private http: Http) { }

  get(): Observable<MyDataModel>{
    return this.http
      .get(this.url)
      .map((res: Response) => res.json());
  }
}

***请参阅Angular 5的底部服务更新***

现在您的组件代码(“ ng g component MyExample”):

my-example.component.ts:

import { Component, OnDestroy, OnInit } from '@angular/core';
import { MyDataModel } from "../my-data-model";
import { MyExampleService } from "../my-example.service";
import { Observable } from "rxjs";
import { IntervalObservable } from "rxjs/observable/IntervalObservable";
import 'rxjs/add/operator/takeWhile';

@Component({
  selector: 'app-my-example',
  templateUrl: './my-example.component.html',
  styleUrls: ['./my-example.component.css']
})
export class MyExampleComponent implements OnInit, OnDestroy {
  private data: MyDataModel;
  private display: boolean; // whether to display info in the component
                            // use *ngIf="display" in your html to take
                            // advantage of this

  private alive: boolean; // used to unsubscribe from the IntervalObservable
                          // when OnDestroy is called.

  constructor(private myExampleService: MyExampleService) {
    this.display = false;
    this.alive = true;
  }

  ngOnInit() {
    // get our data immediately when the component inits
    this.myExampleService.get()
      .first() // only gets fired once
      .subscribe((data) => {
        this.data = data;
        this.display = true;
      });

    // get our data every subsequent 10 seconds
    IntervalObservable.create(10000)
      .takeWhile(() => this.alive) // only fires when component is alive
      .subscribe(() => {
        this.myExampleService.get()
          .subscribe(data => {
            this.data = data;
          });
      });
  }

  ngOnDestroy(){
    this.alive = false; // switches your IntervalObservable off
  }
}

===编辑===

更新了组件ts代码以通过TimerObservable合并订阅:

import { Component, OnDestroy, OnInit } from '@angular/core';
import { MyDataModel } from "../my-data-model";
import { MyExampleService } from "../my-example.service";
import { Observable } from "rxjs";
import { TimerObservable } from "rxjs/observable/TimerObservable";
import 'rxjs/add/operator/takeWhile';

@Component({
  selector: 'app-my-example',
  templateUrl: './my-example.component.html',
  styleUrls: ['./my-example.component.css']
})
export class MyExampleComponent implements OnInit, OnDestroy {
  private data: MyDataModel;
  private display: boolean; // whether to display info in the component
                            // use *ngIf="display" in your html to take
                            // advantage of this

  private alive: boolean; // used to unsubscribe from the TimerObservable
                          // when OnDestroy is called.
  private interval: number;

  constructor(private myExampleService: MyExampleService) {
    this.display = false;
    this.alive = true;
    this.interval = 10000;
  }

  ngOnInit() {
    TimerObservable.create(0, this.interval)
      .takeWhile(() => this.alive)
      .subscribe(() => {
        this.myExampleService.get()
          .subscribe((data) => {
            this.data = data;
            if(!this.display){
              this.display = true;
            }
          });
      });
  }

  ngOnDestroy(){
    this.alive = false; // switches your TimerObservable off
  }
}

===编辑===

my-example-service.ts(使用Angular 5的HttpClient):

import { Injectable } from '@angular/core';
import { HttpClient} from "@angular/common/http";
import { MyDataModel } from "./my-data-model";
import { Observable } from "rxjs";
import 'rxjs/Rx';

@Injectable()
export class MyExampleService {
  private url = 'http://localhost:3000'; // full uri of the service to consume here

  constructor(private http: HttpClient) { }

  get(): Observable<MyDataModel>{
    return this.http
      .get<MyDataModel>(this.url);
  }
}

请注意更改以使用HttpClient而不是Http(在angular5中已弃用)和get方法,该方法允许将响应解析为我们的数据模型,而不必使用rxjs .map()运算符。当服务更改为角度5时,组件代码保持不变。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何从SQL Server发出HTTP请求?

来自分类Dev

如何使用grequests发出HTTP POST请求

来自分类Dev

如何在PHP中发出HTTP请求?

来自分类Dev

如何在Delphi中发出HTTP补丁请求

来自分类Dev

如何在NodeJS的循环内发出HTTP请求

来自分类Dev

如何从COBOL发出HTTP请求

来自分类Dev

在我的情况下,如何发出多个http请求?

来自分类Dev

如何通过Cookie发出HTTP请求

来自分类Dev

发出每个HTTP请求时如何获取用户日期

来自分类Dev

如何发出多个http呼叫请求(Nodejs)

来自分类Dev

Firefox附加组件-如何发出http请求

来自分类Dev

如何在AngularJS 2.0中发出HTTP请求

来自分类Dev

如何在Google Glass GDK上发出HTTP GET请求

来自分类Dev

给定以下HTTP + JSON,如何使用PHP发出POST请求

来自分类Dev

如何使用任务并行库发出许多HTTP请求

来自分类Dev

如何使用HTTP拦截器发出HTTP请求

来自分类Dev

如何使用Deno发出HTTP客户端请求

来自分类Dev

如何从Google脚本向BigQuery发出正确的HTTP请求

来自分类Dev

如何查看网络上发出的http请求?

来自分类Dev

如何在PHP中发出HTTP请求?

来自分类Dev

如何使用Plink发出HTTP请求

来自分类Dev

如何发出多个http请求?

来自分类Dev

如何间隔发出HTTP请求?

来自分类Dev

如何从原始数据发出HTTP请求?

来自分类Dev

如何使用 RxNET 发出异步 HTTP 请求?

来自分类Dev

如何从 EJB 发出 HTTP 请求?

来自分类Dev

如何在工厂中发出http请求

来自分类Dev

aiohttp:如何发出简单的 http 请求

来自分类Dev

如何使用请求发出 HTTP HEAD 请求?