我正在创建一个带有打字稿的角度4应用程序。
我有一个需要每10秒执行一次的功能,直到指定的停止条件。我使用setTimeout创建了一个包含一些测试代码的循环,看看它是否可行。
我的测试代码:
public run() {
let i = 0;
while (i < 4) {
setTimeout(this.timer,3000);
i++;
}
}
public timer(){
console.log("done")
}
然而,这似乎等了3秒,或浏览器只是慢...... 然后它完成了4次打印。所以代码不起作用。我做错了还是有其他可能做这种事情?
答案 0 :(得分:28)
由于您使用的是Angular,因此您可以使用takeWhile
以更简单的方式执行此操作:
Observable.interval(10000)
.takeWhile(() => !stopCondition)
.subscribe(i => {
// This will be called every 10 seconds until `stopCondition` flag is set to true
})
答案 1 :(得分:5)
是的,你做错了:你有一个循环告诉我连续4次执行timer()
3秒后,从现在开始。
要做你想做的事,你每次调用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());
答案 2 :(得分:2)
这确实不是使用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;
}
}
这将在每10秒后运行execute
方法,与stopCondition === false
一样长。当stopCondition === true
输出done
时。
答案 3 :(得分:2)
我将使用 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
}
);
});
}
答案 4 :(得分:1)
使用setInterval(hander:(args:any[]),ms:Number,args:any[])
函数OnInit
,setInterval(a=>{
alert("yes....");
},10000,[]);
。
export function x() { /* ... */ }
export const y = /* ... */;
export class C1 { /* ... */ }
将显示警告&#34;是&#34; 10秒后。
答案 5 :(得分:0)
是的,这是正确的行为。你有同步循环,它创建了4个延迟动作并结束了这个循环。它发生在几毫秒内。因此,所有4个延迟动作都会在3秒钟内同时启动。
因此,在3秒内,您将收到此延迟行动的所有4个回复。
如果您想要执行后果调用(首先在3秒后,然后在第一个之后),请考虑使用promises,并在上次完成后以3秒延迟调用新承诺。
fisrtPromise
.then(secondPromise)
.then(thirdPromise);
https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Global_Objects/Promise
答案 6 :(得分:0)
由于你在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")
}