settimeout angular 5
Angular 4 setTimeout no espera (7)
Estoy creando una aplicación angular 4 con mecanografiado.
Tengo una función que debe ejecutarse cada 10 segundos hasta una condición de parada específica. Creé un bucle con un código de prueba usando setTimeout para ver si funcionaría.
Mi código de prueba:
public run() {
let i = 0;
while (i < 4) {
setTimeout(this.timer,3000);
i++;
}
}
public timer(){
console.log("done")
}
Sin embargo, esto parece esperar 3 segundos, o el navegador es lento ... y luego se imprime 4 veces. Así que el código no funciona. ¿Estoy haciendo esto mal o hay otras posibilidades para hacer este tipo de cosas?
De hecho, esta no es la manera de usar un método async
. El bucle while solo lo hace 4 veces de una vez, e inicia los 4 temporizadores. Que saldrá simultáneamente también en 3 segundos. Sin embargo, puede aprovechar la funcionalidad async
y async
de TypeScript:
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;
}
}
Esto ejecutará el método de execute
después de cada 10 segundos, mientras el stopCondition === false
. Cuando el stopCondition === true
saldrá done
.
Debido a que está llamando a setTimeout dentro del bucle while y debido a la ejecución asíncrona de sentencias, no esperará para ejecutar la función de temporizador antes de pasar a la siguiente iteración. Puede lograr la funcionalidad requerida utilizando el siguiente código
public run() {
var i = 0;
var interval = setInterval(() => {
if (++i === 4) {
clearInterval(interval);
}
else {
this.timer();
}
}, 3000);
}
public timer() {
console.log("done")
}
Lo haré con Angular 6 . Este código solicita cada 5 segundos para obtener el progreso de la representación. Se detendrá el envío de solicitud cuando el progreso llegue a% 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
}
);
});
}
Sí, es el comportamiento correcto. Tiene un bucle síncrono que creó 4 acciones retrasadas y finaliza este bucle. Sucede en pocos milisegundos. Por lo tanto, las 4 acciones retrasadas se registran para iniciarse en 3 segundos, aproximadamente al mismo tiempo.
Así que en 3 segundos recibirá las 4 respuestas de estas acciones demoradas.
Si desea tener una ejecución de llamada de consecuencia (primero después de 3 segundos, luego segundo después del primero) considere usar promesas para esto y haga una nueva promesa con un retraso de 3 segundos después de la finalización previa.
fisrtPromise
.then(secondPromise)
.then(thirdPromise);
https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Global_Objects/Promise
Sí, lo estás haciendo mal: tienes un bucle que indica 4 veces seguidas para ejecutar el timer()
3 segundos más tarde, a partir de ahora.
Para hacer lo que quieras, deberías reprogramar el siguiente temporizador cada vez que se llame al timer()
, o, más simplemente, usar setInterval()
:
let count = 0;
const interval = window.setInterval(() => {
this.timer();
count++;
if (count >= 4) {
window.clearInterval(interval);
}
}, 3000);
Tenga en cuenta que, dado que está usando angular, usar observables sería mucho más fácil:
Observable.interval(3000).take(4).subscribe(() => this.timer());
Utilice la función setInterval(hander:(args:any[]),ms:Number,args:any[])
que es uno de los métodos de OnInit
.
setInterval(a=>{
alert("yes....");
},10000,[]);
Se mostrará alerta "sí" después de 10 segundos.
Ya que está usando Angular, probablemente pueda hacer esto de una manera mucho más simple usando takeWhile
:
Observable.interval(10000)
.takeWhile(() => !stopCondition)
.subscribe(i => {
// This will be called every 10 seconds until `stopCondition` flag is set to true
})