web-dev-qa-db-fra.com

Angular 4 setTimeout () avec un délai et une attente variables

J'ai une liste d'événements avec timestamp. Ce que je veux, c’est d’afficher les événements en fonction de la timestamp

Pour ajouter un délai: 

delay = timestamp(t+1) - timstamp(t)

Je sais que cela ne fonctionne pas bien avec setTimeout, mais il existe une solution de contournement. Si le délai d'attente est constant, dans mon cas, ce n'est pas le cas. 

Est-il possible de faire attendre la prochaine setTimeout() pour la précédente? Pour être précis, si la première setTimeout() a un délai de 5 secondes et que le second a 3 secondes, le second apparaît en premier. Je veux qu'ils soient dans le même ordre mais exécutent les uns après les autres.

Cet exemple fonctionne avec un délai constant, mais je souhaite calculer le délai en fonction des informations que je prends en itérant la liste. 

for (i = 1; i <= 5; ++i) {
  setDelay(i);
}

function setDelay(i) {
  setTimeout(function(){
    console.log(i);
  }, 1000);
}
4
Cristina

Ici, vous pouvez utiliser IIFE (expression de fonction immédiatement appelée) et une récursion de fonction comme:

var i = 0;
(function repeat(){
    if (i++ > 5) return;
    setTimeout(function(){
    console.log("Iteration" + i);
    repeat();
    }, 5000);
})();

Live violon ici .

2
Rohit Sharma

Vous pouvez définir le délai d'expiration en utilisant i value dynamiquement. Comme

for (i = 1; i <= 5; ++i) {
  setDelay(i);
}

function setDelay(i) {
  setTimeout(function(){
    console.log(i);
  }, i*1000);
}
0
Ashok

N'appelez pas cela dans une boucle, car il n'attendra pas que setTimeout soit terminé.

Vous pouvez plutôt passer une liste de fois que vous voulez attendre et les parcourir de manière récursive:

let waits = [5000, 3000, 1000];

function setDelay(times) {
  if (times.length > 0) {
    // Remove the first time from the array
    let wait = times.shift();
    console.log("Waiting", wait);
    
    // Wait for the given amount of time
    setTimeout(() => {
        console.log("Waited ", wait);
        // Call the setDelay function again with the remaining times
        setDelay(times);
    }, wait);
  }
}

setDelay(waits);

0
user184994

Vous pouvez penser à quelque chose comme ça:

setDelay(1,5);

function setDelay(i, max) {
  setTimeout(function(){
    console.log(i);
    if(i < max){
      i++;
      setDelay(i, max);
    }
  }, 1000);
}

L'idée est de définir le prochain setTimeout(.. dans un délai d'attente . Bien sûr, vous pouvez le modifier pour qu'il dispose également de délais longs différents.

J'espère pouvoir aider :)

0
Mattstir

Lorsque vous utilisez le dernier code TypeScript ou ES, nous pouvons utiliser aync/wait pour cela.

let timestampDiffs = [3, 2, 4];

(async () => {
  for (let item of timestampDiffs) {
    await timeout(item * 1000);
    console.log('waited: ' + item);
  }
})();

function timeout(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

Nous devons envelopper la boucle for dans une fonction immédiatement appelée asynchrone, car elle prend en charge wait. 

Nous avons également besoin d'une fonction de délai d'attente qui renvoie une promesse une fois le délai d'attente écoulé.

Après cela, nous attendons la fin du délai d'attente avant de poursuivre la boucle. 

0
nipuna777