TypeScriptでangular 4アプリを作成しています。
指定した停止条件まで10秒ごとに実行する必要がある関数があります。 setTimeoutを使用してテストコードでループを作成し、動作するかどうかを確認しました。
私のテストコード:
public run() {
let i = 0;
while (i < 4) {
setTimeout(this.timer,3000);
i++;
}
}
public timer(){
console.log("done")
}
ただし、これは3秒間待機するように見えます。または、ブラウザが遅いだけです...そして、4回印刷されます。そのため、コードは機能していません。私はこれを間違っていますか、この種のことを行う他の可能性がありますか?
Angularを使用しているため、おそらく takeWhile
を使用して、これをはるかに簡単な方法で実行できます。
Observable.interval(10000)
.takeWhile(() => !stopCondition)
.subscribe(i => {
// This will be called every 10 seconds until `stopCondition` flag is set to true
})
はい、間違っています:3秒後にtimer()
を実行するように連続して4回繰り返すループがあります。
必要なことを行うには、timer()
が呼び出されるたびに次のタイマーを再スケジュールするか、より単純に setInterval()
を使用する必要があります。
let count = 0;
const interval = window.setInterval(() => {
this.timer();
count++;
if (count >= 4) {
window.clearInterval(interval);
}
}, 3000);
角度を使用しているため、オブザーバブルを使用する方がはるかに簡単です。
Observable.interval(3000).take(4).subscribe(() => this.timer());
Angular 6でやった。このコードは、レンダリングの進行状況を取得するために5秒ごとに要求します。進行状況が%100に達すると、要求の送信を停止します。
import {interval} from "rxjs";
getProgress(searchId): void{
const subscription = interval(5000)
.subscribe(()=>{
//Get progress status from the service every 5 seconds
this.appService.getProgressStatus(searchId)
.subscribe((jsonResult:any)=>{
//update the progress on UI
//cancel subscribe until it reaches %100
if(progressPercentage === 100)
subscription.unsubscribe();
},
error => {
//show errors
}
);
});
}
これは実際、async
メソッドを使用する方法ではありません。 while
ループは、一度に4回だけループし、4つのタイマーを開始します。 3秒以内に同時に出力されます。ただし、TypeScriptのawait
およびasync
機能を活用できます。
public stopCondition: boolean = false;
public async run(): Promise<void> {
while (!this.stopCondition) {
await new Promise<void>(resolve => {
setTimeout(resolve, 10000);
});
this.execute();
}
console.log('done');
}
public execute(): void {
if ('whatever should trigger your stop condition') {
this.stopCondition = true;
}
}
これは、stopCondition === false
の間、10秒ごとにexecute
メソッドを実行します。 stopCondition === true
は、done
を出力します。
OnInit
のメソッドの1つである関数setInterval(hander:(args:any[]),ms:Number,args:any[])
を使用します。
setInterval(a=>{
alert("yes....");
},10000,[]);
10秒後にアラート「はい」が表示されます。
Whileループ内でsetTimeoutを呼び出しているため、ステートメントの非同期実行のため、次の反復に進む前にTimer関数の実行を待機しません。以下のコードを使用して必要な機能を実現できます
public run() {
var i = 0;
var interval = setInterval(() => {
if (++i === 4) {
clearInterval(interval);
}
else {
this.timer();
}
}, 3000);
}
public timer() {
console.log("done")
}
はい、それは正しい動作です。 4つの遅延アクションを作成し、このループを終了する同期ループがあります。それは数ミリ秒で起こります。したがって、4つの遅延アクションはすべて、ほぼ同時に3秒で開始されるように登録されます。
したがって、3秒で、この遅延アクションから4つの応答すべてを受け取ることになります。
結果呼び出しの実行(最初は3秒後、2番目は最初)を行うには、これにpromiseを使用し、前の完了から3秒遅れて新しいpromiseを呼び出すことを検討してください。
fisrtPromise
.then(secondPromise)
.then(thirdPromise);
https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Global_Objects/Promise