Corretto modo di attendere che una function finisca prima di continuare?

Ho due funzioni JS. Si chiama l'altro. All'interno della function di chiamata, vorrei call l'altro, aspettare che la function finisca, quindi continuare. Quindi, ad esempio / pseudo codice:

function firstFunction(){ for(i=0;i<x;i++){ // do something } }; function secondFunction(){ firstFunction() // now wait for firstFunction to finish... // do something else }; 

Ho trovato questa soluzione, ma non so se è un modo intelligente per farlo.

 var isPaused = false; function firstFunction(){ isPaused = true; for(i=0;i<x;i++){ // do something } isPaused = false; }; function secondFunction(){ firstFunction() function waitForIt(){ if (isPaused) { setTimeout(function(){waitForIt()},100); } else { // go do that thing }; } }; 

È quella legittima? C'è un modo più elegante per gestirlo? Forse con jQuery?

Un modo per affrontare il lavoro asincrono come questo è quello di utilizzare una function di richiamata, ad esempio:

 function firstFunction(_callback){ // do some asynchronous work // and when the asynchronous stuff is complete _callback(); } function secondFunction(){ // call first function and pass in a callback function which // first function runs when it has completed firstFunction(function() { console.log('huzzah, I\'m done!'); }); } 

Come per la proposta di @Janaka Pushpakumara, ora è ansible utilizzare le funzioni freccia per get la stessa cosa. Per esempio:

firstFunction(() => console.log('huzzah, I\'m done!'))

Sembra che tu sia mancante un punto importnte: JavaScript è un ambiente di esecuzione singolo thread. Vediamo di nuovo il tuo codice, nota che ho aggiunto l' alert("Here") :

 var isPaused = false; function firstFunction(){ isPaused = true; for(i=0;i<x;i++){ // do something } isPaused = false; }; function secondFunction(){ firstFunction() alert("Here"); function waitForIt(){ if (isPaused) { setTimeout(function(){waitForIt()},100); } else { // go do that thing }; } }; 

Non c'è bisogno di aspettare che si sia isPaused . Quando si visualizza l'avviso "Qui", l' isPaused sarà già firstFunction e la firstFunction verrà restituita. Questo perché non puoi "cedere" dall'interno del for loop ( // do something ), il ciclo non può essere interrotto e dovrà completare completamente (per maggiori dettagli: la gestione del thread Javascript e le condizioni di gara ).

Detto questo, è comunque ansible effettuare il stream di codice all'interno di firstFunction per essere asincrono e utilizzare il callback o la promise di notificare al chiamante. Dovresti rinunciare for ciclo e simularlo if invece ( JSFiddle ):

 function firstFunction() { var deferred = $.Deferred(); var i = 0; var nextStep = function() { if (i<10) { // Do something printOutput("Step: " + i); i++; setTimeout(nextStep, 500); } else { deferred.resolve(i); } } nextStep(); return deferred.promise(); } function secondFunction() { var promise = firstFunction(); promise.then(function(result) { printOutput("Result: " + result); }); } 

Su una nota laterale, JavaScript 1.7 ha introdotto la parola chiave del yield come parte di generatori . Ciò consentirà di "punch" i fori asincroni in un stream di codice JavaScript in modo sincrono ( ulteriori dettagli e un esempio ). Tuttavia, il supporto del browser per i generatori è attualmente limitato a Firefox e Chrome, AFAIK.

La risposta migliore è in realtà molto semplice. prima di utilizzare setTimeout la function di avviso è apparsa prima che l'image venisse visualizzata. Ora il pic mostra prima dell'allarme.

 Showimg("mypic.jpg"); setTimeout('alert("You See Pic First")',1000) function Showimg(s){ document.getElementById("imgcel").src=s; }