2010-11-08 23 views
40

tengo el siguiente escenario:usando setTimeout sincrónicamente en JavaScript

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

necesito el código después de la setTimeout a ejecutar después de ejecutar el código en el setTimeout. Como el código que viene después del setTimeout no es un código propio, no puedo ponerlo en la función llamada en el setTimeout ...

¿Hay alguna forma de evitar esto?

Respuesta

51

¿El código está en una función?

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

    // code that you cannot modify? 
} 

En ese caso, se podría prevenir la función de ejecución adicional, y luego ejecutarlo de nuevo:

function test(flag) { 

    if(!flag) { 

     setTimeout(function() { 

      alert(); 
      test(true); 

     }, 5000); 

     return; 

    } 

    // code that you cannot modify 

} 
+0

Esto es de hecho una solución aceptable, ¡Genial! – Nathan

+0

esto es genial! pero el mío es un caso completamente similar a excepción de que hay mucho código de estructura que se encuentra por encima de la llamada setTimeout también, y no se puede hacer que se ejecute de nuevo ... y no será posible dividir mi código en diferentes funciones desde el punto donde setTimeout entra en acción. – mickeymoon

+2

@David Hedlund: Este es un buen enfoque, pero ¿hay alguna manera de hacer que el código sea sincrónico cuando el código no está en una función? –

5

No, ya que no hay función de demora en Javascript, no hay otra manera de hacerlo que esperar ocupado (lo que bloquearía el navegador).

+0

¿Puede por favor elaborar la idea de espera ocupado y su funcionamiento. –

+5

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

+0

Siempre evito mientras controlo sin estrangulamiento – tom10271

6

sólo hay que poner el interior de la devolución de llamada:

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

¿Pero él no tiene acceso al código que dispara el' setTimeout'? – Marko

+0

Y como el código que viene después de setTimeout no es un código propio, no puedo ponerlo en la función llamada en setTimeout ... Estoy trabajando con un framework, así que no puedo simplemente poner el código de marcos en allí ... – Nathan

+0

Perdón por leer mal. Bueno, entonces no tienes suerte. 'setTimeout' si siempre es asincrónico. –

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

Se podría intentar reemplazar window.setTimeout con su propia función, al igual que

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

que puede o puede no funcionar correctamente en absoluto. Además de esto, tu única opción sería cambiar el código original (que dijiste que no podías hacer)

Ten en cuenta que cambiar las funciones nativas de esta manera no es exactamente un enfoque muy óptimo.

26

que se produjo en una situación en la que necesitaba una funcionalidad similar la semana pasada y me hizo piensa en esta publicación. Básicamente, creo que la "Espera ocupada" a la que se refiere @AndreKR, sería una solución adecuada en muchas situaciones. Debajo está el código que usé para encerrar el navegador y forzar una condición de espera.

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");

Tenga en cuenta que este código tiene acutally su navegador. Espero que ayude a cualquiera.

+0

En realidad, esto no detiene la ejecución del script, pero el siguiente script (después de la función de pausa de llamada) se ejecutará una vez finalizado el bucle. Difícil, pero funcionalmente cumple con la necesidad de la pregunta. –

0

ES6 (de espera ocupada)

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

uso:

delay(1000) 
Cuestiones relacionadas