我试图在angular2中每隔x秒刷新一次http调用。
ionViewDidLoad() {
let loader = this.LoadingController.create({
'content':'Please Wait'
});
loader.present().then(()=>{
this.http.request('http://mywebserver.com/apps/random.php').map(res=> res.json()).subscribe(data=>{
console.log(JSON.stringify(data));
loader.dismiss();
this.fact = data;
},err=>{
loader.dismiss();
let alert = this.alertCtrl.create({
title: 'Error!',
subTitle: 'Please check your Internet Connectivity',
buttons: ['OK']
});
alert.present();
})
})
}
我在新加载页面时获取数据。但现在我的问题是刷新http调用以每隔x秒获取新数据
答案 0 :(得分:5)
我会创建一个单独的服务来发出你的http请求:
@Injectable()
export class RandomService {
constructor(http: HttpClient) { }
getRandom() {
return this.http.get('http://mywebserver.com/apps/random.php');
}
}
现在您只需在randomService.getRandom()
内调用setInterval
,但您也可以使用可观察操作(例如Observable.interval
)来ionViewDidLoad
为您处理此问题}:
async function ionViewDidLoad() {
let loader = this.LoadingController.create({
content: 'Please Wait',
});
await loader.present();
// x number of seconds
this.interval$ = interval(x).pipe(
// make first request right away; otherwise we have to wait x seconds before first one
startWith(),
// cancel previous request if it had not finished yet
switchMap(() =>
// catch the error inside to allow for a retry each time
// you could also use `.catch` on the entire observable stream which will
// cancel it if there's an error.
this.randomService.getRandom().catch(err => {
console.error(err);
this.alertCtrl
.create({
title: 'Error!',
subTitle: 'Please check your Internet Connectivity',
buttons: ['OK'],
})
.present();
}),
),
);
this.interval$.subscribe(data => this.fact = data);
// Separate observable to dismiss loader on first emission
this.interval$.pipe(first()).subscribe(() => loader.dismiss());
}
ionViewWillUnload() {
this.interval$.unsubscribe();
}
注意:这是假设使用RxJS 5.5和Angular与HttpClient
。你可能没有这些,但你仍然可以做一些非常相似的事情。你只是无法通过lettable运算符进行管道传输,如果你没有使用HttpClient
,你仍然必须执行.map(data => data.json())
我将在服务中执行此操作。
最后,如果可以,请避免存储和手动取消订阅,如this.interval$
中所述。相反,您可能会执行类似this.fact$ = interval(x)...
的操作。然后在您的模板中,您可以执行*ngFor="let fact of (fact$ | async)"
,而无需手动取消订阅。
答案 1 :(得分:3)
import {Observable} from 'rxjs/Rx';
...
constructor(...) {
Observable.interval(30000).subscribe(x => { // will execute every 30 seconds
this.ionViewDidLoad();
});
}
或ionViewDidLoad
函数内的OR:
Observable.interval(3000)
.timeInterval()
.flatMap(() => this.http.request('http://mywebserver.com/apps/random.php')
.map(res=> res.json())
.subscribe(data=>{
console.log(JSON.stringify(data));
loader.dismiss();
this.fact = data;
});
编辑以回答您的评论。来自Rxjs文档:
timeInterval运算符将源Observable转换为 可观察到发出的时间间隔的指示 连续排放的源Observable。第一次发射 从这个新的Observable中可以看出它之间经过的时间 观察者订阅Observable的时间和时间 当源Observable发出第一个项目时。没有 相应的发射标志着之间经过的时间 最后一次发射源Observable和随后的调用 onCompleted。
默认情况下,timeInterval在超时Scheduler上运行,但也是 有一个变体,允许您通过传递它来指定调度程序 作为参数。
在这种情况下,它基本上是JavaScript的原生setInterval()
函数的反应/ Rxjs方式。