2010-11-08 20 views
40

Ho il seguente scenario:usando setTimeout sincrono in JavaScript

setTimeout("alert('this alert is timedout and should be the first');", 5000); 
alert("this should be the second one"); 

Ho bisogno del codice dopo la setTimeout da eseguire dopo l'esecuzione del codice nella setTimeout. Dal momento che il codice che viene dopo il setTimeout non è il mio codice personale non riesco a metterlo nella funzione chiamata nel setTimeout ...

C'è un modo per aggirare questo?

risposta

51

Il codice è contenuto in una funzione?

function test() { 
    setTimeout(...);  

    // code that you cannot modify? 
} 

In questo caso, si potrebbe evitare che la funzione di ulteriore esecuzione, e quindi eseguirlo di nuovo:

function test(flag) { 

    if(!flag) { 

     setTimeout(function() { 

      alert(); 
      test(true); 

     }, 5000); 

     return; 

    } 

    // code that you cannot modify 

} 
+0

Questa è davvero una soluzione accettabile, Grande! – Nathan

+0

questo è fantastico !! ma il mio è un caso del tutto simile eccetto che c'è molto codice framework che si trova al di sopra della chiamata setTimeout, e non può essere fatto girare di nuovo ... e non sarà possibile dividere il mio codice in funzioni diverse dal punto in cui setTimeout entra in gioco. – mickeymoon

+2

@David Hedlund: Questo è un buon approccio ma esiste un modo per rendere il codice sincrono quando il codice non è in una funzione? –

5

No, poiché non esiste una funzione di ritardo in Javascript, non c'è modo di farlo diversamente dall'attesa (che bloccherebbe il browser).

+0

Potete per favore elaborare l'idea di attesa occupato e il suo funzionamento. –

+5

'var until = new Date(). GetTime() + 3000; while (new Date(). getTime() AndreKR

+0

Evito sempre mentre controllo senza alcuna limitazione – tom10271

6

appena messo dentro il callback:

setTimeout(function() { 
    alert('this alert is timedout and should be the first'); 
    alert('this should be the second one'); 
}, 5000); 
+0

Ma lui non ha accesso al codice che attiva il' setTimeout'? – Marko

+0

E poiché il codice che viene dopo il setTimeout non è il mio codice personale non posso inserirlo nella funzione chiamata nel setTimeout ... Sto lavorando con un framework, quindi non posso semplicemente inserire il codice framework in ci ... – Nathan

+0

Ci scusiamo per la lettura errata. Bene, allora sei sfortunato. 'setTimeout' se sempre asincrono. –

2
setTimeout(function() { 
    yourCode(); // alert('this alert is timedout and should be the first'); 
    otherCode(); // alert("this should be the second one"); 
}, 5000); 
1

Si potrebbe tentare di sostituire window.setTimeout con la propria funzione, in questo modo

window.setTimeout = function(func, timeout) { 
    func(); 
} 

che può o non può funzionare correttamente affatto. Oltre a questo, la tua unica opzione sarebbe quella di cambiare il codice originale (che hai detto che non potevi fare)

Tenere a mente, cambiare le funzioni native come questo non è esattamente un approccio ottimale.

26

sono venuto in una situazione in cui avevo bisogno di una funzionalità simile la scorsa settimana e mi ha fatto pensa a questo post. Fondamentalmente penso che "Occupato in attesa" a cui si riferisce @AndreKR, sarebbe una soluzione adatta in molte situazioni. Di seguito è riportato il codice che ho utilizzato per sollevare il browser e forzare una condizione di attesa.

function pause(milliseconds) { 
 
\t var dt = new Date(); 
 
\t while ((new Date()) - dt <= milliseconds) { /* Do nothing */ } 
 
} 
 

 
document.write("first statement"); 
 
alert("first statement"); 
 

 
pause(3000); 
 

 
document.write("<br />3 seconds"); 
 
alert("paused for 3 seconds");

Tenete a mente che questo codice tiene acutally il browser. Spero che aiuti chiunque.

+0

In realtà, ciò non mette in pausa l'esecuzione dello script, ma lo script successivo (dopo la funzione di interruzione della chiamata) verrà eseguito dopo il ciclo. Ingannevole, ma funzionalmente risponde all'esigenza della domanda. –

0

ES6 (attesa occupato)

const delay = (ms) => { 
    const startPoint = new Date().getTime() 
    while (new Date().getTime() - startPoint <= ms) {/* wait */} 
} 

utilizzo:

delay(1000) 
Problemi correlati