Hay una función de JavaScript, de los cuales tengo el control cero del código, que llama a una función que escribí. Mi función usa DOM para generar un iFrame, define su src y luego lo agrega a otro elemento DOM. Sin embargo, antes de que mi función regrese, y así permita la ejecución continua de la función contenedora, es imperativo que el iFrame esté completamente cargado.La línea de retardo imposible Javascript/sueño
Estas son las cosas que he tratado y por qué no funcionan:
1. La opción SetTimeout:
99,999% de las veces, esta es la respuesta. Como cuestión de hecho, en los últimos diez años que he estado Mentoring en JavaScript, siempre he insistido en que el código siempre podría ser rediseñado para utilizar esta opción, y nunca se cree existió un escenario en que no era el caso. Bueno, ¡finalmente encontré uno! El problema es que debido a mi función está siendo llamado en línea, si se ejecuta la siguiente línea antes de mi iFrame termina de cargar, se neutraliza totalmente mi escritura, y desde el momento en que mi escritura termina, el guión sigue externa. Una devolución de llamada de tipo no funcionará
2. El bucle "No hacer nada":
Esta opción se utiliza, mientras que (// iFrame no está cargado) {// hacer nada}. En teoría, esto no volvería hasta que se cargue el marco. El problema es que, dado que esto encierra todos los recursos, el iFrame nunca se carga. Este truco, aunque terriblemente poco profesional, sucio, etc. funcionará cuando solo necesite un retraso en línea, pero como necesito un hilo externo para completar, no lo hará.
En FF, después de unos segundos, pausa la secuencia de comandos y aparece una alerta que indica que hay una secuencia de comandos que no responde. Mientras la alerta está activa, iFrame puede cargar y luego mi función puede regresar, pero tener el navegador congelado durante 10 segundos y luego requerir que el usuario descarte un error correctamente es no ir.
3. El modelo de diálogo:
Me inspiré en el hecho de que la ventana emergente FF permitió que el marco flotante para cargar mientras que la detención de la ejecución de la función, y pensar en ello, me di cuenta de que es debido a que el modal diálogo, ¡es una forma de detener la ejecución permitiendo que otros hilos continúen! Brillante, así que decidí probar otras opciones modales. Cosas como alert() funcionan muy bien! Cuando aparece, aunque solo sea durante una décima de segundo, el iFrame puede completarse y todo funciona muy bien. Y en caso de que el 1/10 de segundo no sea suficiente, puedo poner el diálogo de modelo en el ciclo while de la solución 2, y garantizaría que el iFrame se cargue a tiempo. Dulce ¿verdad? Excepto por el hecho de que ahora tengo que abrir un diálogo muy poco profesional para que el usuario descarte para ejecutar mi script. Luché conmigo mismo sobre este costo/beneficio de esta acción, pero luego me encontré con un escenario en el que mi código se llamaba 10 veces en una sola página. ¡Tener que descartar 10 alertas antes de acceder a una página! Eso me recuerda a las páginas de guiones de finales de los 90, y NO es una opción.
4. Un otro script retraso tropecientos por ahí:
Hay alrededor de 10 o retardo del sueño funciones de jQuery, algunos de ellos en realidad muy hábilmente desarrollados, pero ninguno funcionó. Algunas opciones de prototipos, y nuevamente, ¡ninguna que encontré podría hacerlo! Una docena más o menos de otras bibliotecas y marcos afirmaron que tenían lo que necesitaba, pero, por desgracia, todos conspiraron para darme falsas esperanzas.
estoy convencido de que ya construido en un modelo de diálogo puede detener la ejecución, al tiempo que permite a otros hilos siguen, tiene que haber alguna manera accesible código para hacer lo mismo con la entrada del usuario a cabo.
El Código es literalmente miles y miles de líneas y es propietaria, así que escribí este pequeño ejemplo del problema para que usted pueda trabajar con ellos.Es importante tener en cuenta el código sólo es capaz de cambiar está en la función onlyThingYouCanChange
archivo de prueba:
<html>
<head>
</head>
</html>
<body>
<div id='iFrameHolder'></div>
<script type='text/javascript'>
function unChangeableFunction()
{
new_iFrame = onlyThingYouCanChange(document.getElementById('iFrameHolder'));
new_iFrame_doc = (new_iFrame.contentWindow || new_iFrame.contentDocument);
if(new_iFrame_doc.document)new_iFrame_doc=new_iFrame_doc.document;
new_iFrame_body = new_iFrame_doc.body;
if(new_iFrame_body.innerHTML != 'Loaded?')
{
//The world explodes!!!
alert('you just blew up the world! Way to go!');
}
else
{
alert('wow, you did it! Way to go!');
}
}
var iFrameLoaded = false;
function onlyThingYouCanChange(objectToAppendIFrameTo)
{
iFrameLoaded = false;
iframe=document.createElement('iframe');
iframe.onload = new Function('iFrameLoaded = true');
iframe.src = 'blank_frame.html'; //Must use an HTML doc on the server because there is a very specific DOM structure that must be maintained.
objectToAppendIFrameTo.appendChild(iframe);
var it = 0;
while(!iFrameLoaded) //I put the limit on here so you don't
{
//If I was able to put some sort of delay here that paused the exicution of the script, but did not halt all other browser threads, and did not require user interaction we'd be golden!
//alert('test'); //This would work if it did not require user interaction!
}
return iframe;
}
unChangeableFunction();
</script>
</body>
blank_frame.html:
<html>
<head>
</head>
<body style='margin:0px'>Loaded?</body>
</html>
Aquí está la respuesta que ¡HECHO DE COMBINAR IDEAS DE RESPONDEDORES! ¡USTEDES MOLAN!
nueva fuente de la función que se le permitió cambiar:
function onlyThingYouCanChange(objectToAppendIFrameTo)
{
iFrameLoaded = false;
iframe=document.createElement('iframe');
iframe.onload = new Function('iFrameLoaded = true');
iframe.src = 'blank_frame.html'; //Must use an HTML doc on the server because there is a very specific DOM structure that must be maintained.
objectToAppendIFrameTo.appendChild(iframe);
var it = 0;
while(!iFrameLoaded) //I put the limit on here so you don't
{
if (window.XMLHttpRequest)
{
AJAX=new XMLHttpRequest();
}
else
{
AJAX=new ActiveXObject("Microsoft.XMLHTTP");
}
if (AJAX)
{
AJAX.open("GET", 'slow_page.php', false);
AJAX.send(null);
}
else
{
alert('something is wrong with AJAX!');
}
//If I was able to put some sort of delay here that paused the exicution of the script, but did not halt all other browser threads, and did not require user interaction we'd be golden!
//alert('test'); //This would work if it did not require user interaction!
}
return iframe;
}
slow_page.php:
<?
usleep(100000);//sleep for 1/10th of a second, to allow iFrame time to load without DOSing our own server!
?>
sí quiero señalar que he dicho que no había nada fuera de esa función que me podría cambiar, y agregar la página php sí violaba esa "regla", pero en el caso de que fuera capaz de hacerlo. Si no fuera capaz de hacerlo, I podría haber llamado blank_frame.html en lugar de slow_page.php, y solo debería haber sido necesario llamarlo una vez (por lo que 2 veces por carga de cuadro) suponiendo que respondiera de forma idéntica cantidad de tiempo que carga el iFrame. Si por alguna razón la carga de iFrame fuera más lenta, podría llamarla 2ce (un total de 3 llamadas al servidor)
No se puede combinar 'new Function() {return code; } 'con la devolución de llamada de' setTimeout'? –
Personalmente, creo que cualquier diseño que requiera que este sea el caso es altamente defectuoso, pero desde una perspectiva académica me interesaría ver si hay una respuesta. –
meder, setTimeout permitirá la ejecución continua de Javascript, a menos que tenga una forma de combinar aquellos que no conozco. Mencioné algunos complementos de jQuery que hicieron algunas cosas muy ingeniosas, con eso, pero analicé todo lo que pude encontrar y ninguno funcionó para mí. Si puede encontrar la manera de hacerlo funcionar en el ejemplo anterior, ¡estaría encantado! Brian. Estoy de acuerdo con usted 99.999%, y hace unos días habría dicho 100%, y habría discutido con cualquiera que dijera que era necesaria una demora en línea. Desafortunadamente no tengo el control para arreglarlo aquí! – trex005