web-dev-qa-db-fra.com

fonction javascript attendez qu'une autre fonction se termine

J'ai deux fonctions javascript appelées depuis Android. Après de longues sessions de débogage, j'ai finalement réalisé que le problème venait du fait que la deuxième fonction est appelée avant la fin de la première. J'ai déjà recherché les exemples avec différé, etc., mais ils dépendent tous d'appels de fonction dans un autre.

function FunctInit(someVarible){ //someVariable is sent from Android, cannot call again from getResult
//init and fill screen
}

function getResult(){ //also getResult need to be called from Android via button
//return some variables
}

Comment puis-je forcer getResult à attendre FuncInit? Existe-t-il un moyen d'y parvenir via Javascript?

12
tugce

À mon avis, les reports/promesses (comme vous l'avez mentionné) est la voie à suivre, plutôt que d'utiliser des délais d'attente.

Voici un exemple Je viens d'écrire pour montrer comment vous pouvez le faire en utilisant des reports/promesses.

Prenez le temps de jouer avec les différés. Une fois que vous les comprenez vraiment, il devient très facile d'effectuer des tâches asynchrones.

J'espère que cela t'aides!

$(function(){
    function1().done(function(){
        // function1 is done, we can now call function2
        console.log('function1 is done!');

        function2().done(function(){
            //function2 is done
            console.log('function2 is done!');
        });
    });
});

function function1(){
    var dfrd1 = $.Deferred();
    var dfrd2= $.Deferred();

    setTimeout(function(){
        // doing async stuff
        console.log('task 1 in function1 is done!');
        dfrd1.resolve();
    }, 1000);

    setTimeout(function(){
        // doing more async stuff
        console.log('task 2 in function1 is done!');
        dfrd2.resolve();
    }, 750);

    return $.when(dfrd1, dfrd2).done(function(){
        console.log('both tasks in function1 are done');
        // Both asyncs tasks are done
    }).promise();
}

function function2(){
    var dfrd1 = $.Deferred();
    setTimeout(function(){
        // doing async stuff
        console.log('task 1 in function2 is done!');
        dfrd1.resolve();
    }, 2000);
    return dfrd1.promise();
}
40
Antoine Cloutier

Il y a plusieurs façons de penser à cela.

Utilisez un rappel:

 function FunctInit(someVarible){
      //init and fill screen
      AndroidCallGetResult();  // Enables Android button.
 }

 function getResult(){ // Called from Android button only after button is enabled
      //return some variables
 }

Utilisez un délai d'attente (ce serait probablement ma préférence):

 var inited = false;
 function FunctInit(someVarible){
      //init and fill screen
      inited = true;
 }

 function getResult(){
      if (inited) {
           //return some variables
      } else {
           setTimeout(getResult, 250);
      }
 }

Attendez que l'initialisation se produise:

 var inited = false;
 function FunctInit(someVarible){
      //init and fill screen
      inited = true;
 }

 function getResult(){
      var a = 1;
      do { a=1; }
      while(!inited);
      //return some variables
 }
6
Nicholas

La réponse suivante peut vous aider dans cette situation et dans d'autres situations similaires comme synchrone AJAX call -

Fonctionnement exemple

waitForMe().then(function(intentsArr){
  console.log('Finally, I can execute!!!');
},
function(err){
  console.log('This is error message.');
})

function waitForMe(){
    // Returns promise
    console.log('Inside waitForMe');
    return new Promise(function(resolve, reject){
        if(true){ // Try changing to 'false'
            setTimeout(function(){
                console.log('waitForMe\'s function succeeded');
                resolve();
            }, 2500);
        }
        else{
            setTimeout(function(){
                console.log('waitForMe\'s else block failed');
                resolve();
            }, 2500);
        }
    });
}
1
Sujit Kumar Singh