Angular 4 setTimeout不等待

时间:2017-07-12 12:06:42

标签: angular typescript settimeout

我正在创建一个带有打字稿的角度4应用程序。

我有一个需要每10秒执行一次的功能,直到指定的停止条件。我使用setTimeout创建了一个包含一些测试代码的循环,看看它是否可行。

我的测试代码:

public run() {
    let i = 0;
    while (i < 4) {
        setTimeout(this.timer,3000);
        i++;
    }
}

public timer(){
    console.log("done")
}

然而,这似乎等了3秒,或浏览器只是慢...... 然后它完成了4次打印。所以代码不起作用。我做错了还是有其他可能做这种事情?

7 个答案:

答案 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中的awaitasync功能:

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[])函数OnInitsetInterval(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")
}