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?
À 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();
}
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
}
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);
}
});
}