2010-09-21 45 views
10

¿Hay alguna forma en JavaScript para enviar una solicitud HTTP a un servidor HTTP y esperar hasta que el servidor responda con una respuesta? Quiero que mi programa espere hasta que el servidor responda y no ejecute ningún otro comando posterior a esta solicitud. Si el servidor HTTP está inactivo, quiero que la solicitud HTTP se repita después de un tiempo de espera hasta que el servidor responda, y luego la ejecución del programa puede continuar normalmente.Cómo forzar a un programa a esperar hasta que se complete una solicitud HTTP en JavaScript?

¿Alguna idea?

gracias de antemano, Thanasis

+6

Me gustaría que la gente dejar comentarios explicativos cuando -1. – kojiro

Respuesta

10

Puede realizar una petición síncrona. jQuery ejemplo:

$(function() { 
    $.ajax({ 
     async: false, 
     // other parameters 
    }); 
}); 

Usted debe echar un vistazo a jQuery de AJAX API. Recomiendo usar un framework como jQuery para esto. ¡Hacer manualmente ajax de navegador cruzado es un verdadero dolor!

+0

¡esta es la mejor manera! Sin embargo, muchas personas piensan que JS Frameworks es malo y tienden a codificar todo por sí mismos. – Alex

+0

He intentado hacerlo de varias maneras usando XmlHttpRequest por ejemplo, pero no he encontrado la manera de detener la ejecución hasta que reciba una respuesta ... –

+4

Alex, ese soy yo! ¡Yo soy uno de ellos! ;) –

0

Para esto puede iniciar el cargador en javascript tan pronto como la página comience a cargarse y luego puede cerrarlo cuando la solicitud finalice o su dom esté listo. Lo que intento decir, a medida que se inicia la carga de la página, iniciar un cargador. A continuación, la página puede hacer varias solicitudes sincrónicas utilizando ajax, hasta que, a menos que no haya recibido respuesta, no cierre el cargador cercano. Después de recibir el deseado en respuesta en la llamada final, puede cerrar el cargador.

+1

está fuera ... él es preguntando por el estancamiento de múltiples solicitudes. – Alex

+0

Sí, eso es exactamente lo que quiero hacer ... –

+0

@Thanasis Petsas: compruebe la publicación editada. Espero que esto le pueda ayudar. – Nik

2

Puede usar el objeto XMLHttpRequest para enviar su solicitud. una vez que envíe su solicitud, puede declarar la propiedad State para identificar el estado. readyState tendrá los siguientes estados diferentes.

  • sin inicializar - no se empieza a cargar todavía
  • carga - se está cargando
  • interactiva - se ha cargado lo suficiente y el usuario puede interactuar con él
  • completa - A plena carga

por ejemplo:

xmlhttp.open("GET","somepage.xml",true); 
xmlhttp.onreadystatechange = checkData; 
xmlhttp.send(null); 

function checkData() 
{ 
    alert(xmlhttp.readyState); 
} 

hope this ayudará

+0

Quiero que la ejecución del programa sea en serie y no quiero utilizar devoluciones de llamada. Deseo, si es posible, detener la ejecución del programa en "xmlhttp.send (null);" llame y luego continúe después de que la solicitud haya finalizado. –

+0

Puede jugar con la propiedad readyState. Puede ser que pueda colocarlo en el ciclo while y para que no pase a la siguiente línea hasta que la ejecución finalice. Además, si puede predecir el tiempo de ejecución, puede usar la función setTimeOut(). más sobre esta función puede leer aquí. http://www.w3schools.com/jsref/met_win_settimeout.asp – Akie

0

Tengo una situación similar en un juego creado con Three.js y Google Closure. Tengo que cargar 2 recursos, Three y Closure no me permiten hacer estos sincrónicos.

Inicialmente ingenuamente escribió lo siguiente:

main() { 

    ... 
    var loaded=0; 
    ... 

    // Load Three geometry 
    var loader = new THREE.JSONLoader(); 
    loader.load("x/data.three.json", function(geometry) { 
    ... 
    loaded++; 
    }); 

    // Load my engine data 
    goog.net.XhrIo.send("x/data.engine.json", function(e) { 
    var obj = e.target.getResponseJson(); 
    ... 
    loaded++; 
    }); 

    // Wait for callbacks to complete 
    while(loaded<2) {} 

    // Initiate an animation loop 
    ... 
}; 

El bucle que espera a que las devoluciones de llamada para completar nunca termina, desde el punto de vista del bucle loaded nunca se incrementa. El problema es que las devoluciones de llamada no se activan hasta que main regresa (al menos en Chrome de todos modos).

Una solución podría consistir en revisar ambas devoluciones de llamada para ver si es la última en completarse, y luego iniciar el ciclo de animación.

Otra solución - tal vez una respuesta más directa a lo que están pidiendo (cómo esperar para cada carga antes de iniciar otra) - sería anidar las devoluciones de llamada de la siguiente manera:

// Load Three geometry 
var loader = new THREE.JSONLoader(); 
loader.load("x/data.three.json", function(geometry) { 
    ... 

    // Load my engine data 
    goog.net.XhrIo.send("x/data.engine.json", function(e) { 
    var obj = e.target.getResponseJson(); 
    ... 

    // Initiate an animation loop 
    ... 

    }); 
    }); 
}; 
+1

Hola Argenti, bienvenido a stackoverflow! Por favor haz tus respuestas lo más claras posible. Utilice las llaves o ajuste su código con el carácter \ '. Si es posible, intente y vea si puede ejecutar algo antes de publicarlo. Estas preguntas también pueden ser consultadas en el futuro, ¡por favor intente y haga el esfuerzo! –

+0

Encontré esto: Nota: _A partir de Gecko 30.0 (Firefox 30.0/Thunderbird 30.0/SeaMonkey 2.27), las solicitudes síncronas en el hilo principal han quedado obsoletas debido a los efectos negativos para la experiencia del usuario._ [Mozilla Dev.Network] (https : //developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) –

18

hay un tercer parámetro a XmlHttpRequest :: open(), que apunta a indicar que desea que la solicitud sea asincrónica (y así manejar la respuesta a través de un controlador onreadystate).

Así que si quiere que sea sincrónico (es decir, espere la respuesta), simplemente especifique falso para este tercer argumento. Es posible que también desee establecer una propiedad de tiempo de espera limitado para su solicitud en este caso, ya que bloquearía la página hasta la recepción.

Aquí es una función de ejemplo todo-en-uno para tanto síncronas y asíncronas:

function httpRequest(address, reqType, asyncProc) { 
    var r = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"); 
    if (asyncProc) 
     r.onreadystatechange = function() { 
      if (this.readyState == 4) asyncProc(this); 
     }; 
    else 
     r.timeout = 4000; // Reduce default 2mn-like timeout to 4 s if synchronous 
    r.open(reqType, address, !(!asyncProc)); 
    r.send(); 
    return r; 
} 

que se podría llamar de esta manera:

var req = httpRequest("http://example.com/aPageToTestForExistence.html", "HEAD"); // In this example you don't want to GET the full page contents 
alert(req.status == 200 ? "found!" : "failed"); // We didn't provided an async proc so this will be executed after request completion only 
+0

Esto me lleva a la biblioteca asíncrona, lo que hace que esto sea extraordinariamente simple. https://github.com/caolan/async/ No se deje engañar por el cruft de embalaje. ¡Solo incluye un pequeño archivo javascript - async.js! – tudor

Cuestiones relacionadas