J'ai actuellement 5 fonctions; chacun utilise setInterval pour attendre le chargement d'un élément et clique sur l'élément lorsqu'il est disponible, ce qui mène à la page Web suivante. Ces fonctions ont également lieu à l'intérieur d'une boucle while. Il est très important que ces fonctions se déroulent l'une après l'autre et que la boucle while attend que toutes les fonctions se terminent avant de boucler à nouveau. Étant donné que les fonctions sont asynchrones, la boucle s'exécutera x fois avant qu'aucune des fonctions ne puisse même se charger.

Exemple de ce que j'essaie de faire:

function one () {
    var checkForItem = setInterval(function () {
        if ($('#element').length) {
            $('#element').click();
            clearInterval(checkForItem);
        }
    }, 100);
}

Imaginez 5 de ces fonctions (one, two, three, four, five), toutes avec le même format en utilisant setInterval et le boucle while suivante:

var x = 0, y = 10;

while (x < y){
    one();
    two();
    three();
    four();
    five();
    x++
}

Comment pourrais-je m'assurer que toutes les fonctions ont lieu l'une après l'autre avant de continuer la boucle?

Remarque: J'ai essayé d'utiliser des promesses bien qu'en raison des fonctions asynchrones, la boucle continue toujours avant que les fonctions ne soient terminées.

1
Swift Geek 15 avril 2018 à 02:54

3 réponses

Meilleure réponse

Utilisez la syntaxe async / await avec les promesses:

function delay(t) {
    return new Promise(resolve => setTimeout(resolve, t));
}
async function one() {
    while (!$('#element').length) {
        await delay(100);
    }
    $('#element').click();
}

async function main() {
    for (var x = 0; x < 10; x++) {
        await one();
        await two();
        await three();
        await four();
        await five();
    }
}
3
Bergi 15 avril 2018 à 17:46

Essayez de boucler la promesse avec async:

async function one (){
      await (new Promise(function(reolve, reject){
         var checkForItem = setInterval(function () {
           if ($('#element').length) {
              $('#element').click();
              clearInterval(checkForItem);
              resolve();
            }
         }, 100);
      }));
}

//And then in your while loop:
while (x < y){
    await one();
    await two();
    ...
    x++
}

note : votre boucle while doit également être enveloppée dans une fonction asynchrone.

-1
Hank Phung 16 avril 2018 à 07:33

Définissez les sélecteurs dans un tableau et parcourez progressivement le tableau dans l'intervalle jusqu'à ce que la fin du tableau soit atteinte:

const initialSelectorsToFind = ['#element1', '#element2', '#element3']; // add more as desired
const elementSelectorsToFind = Array.from({ length: 10 })
  .reduce(arrSoFar => [...arrSoFar, ...initialSelectorsToFind], []);
let elementIndexToFind = 0;
function tryClick(){
  const elementToFind = $(elementSelectorsToFind[elementIndexToFind]);
  if (elementToFind.length) {
    elementToFind.click();
    elementIndexToFind++;
    if (elementIndexToFind === elementSelectorsToFind.length) {
      clearInterval(tryClickInterval);
    }
  }
}
const tryClickInterval = setInterval(tryClick, 100);

Mais si vous essayez de déclencher une fonction (comme quelque chose qui clique sur un élément) lorsqu'un élément est ajouté au DOM, il vaudrait beaucoup mieux utiliser quelque chose qui déclenche quand l'ajout se produit , comme un rappel dans la fonction créateur ou MutationObserver

0
CertainPerformance 15 avril 2018 à 00:56