2010-09-21 21 views
10

C'è un modo in JavaScript per inviare una richiesta HTTP a un server HTTP e attendere fino a quando il server risponde con una risposta? Voglio che il mio programma attenda che il server risponda e non esegua nessun altro comando dopo questa richiesta. Se il server HTTP non funziona, voglio che la richiesta HTTP venga ripetuta dopo un timeout fino a quando il server non risponde, e quindi l'esecuzione del programma può continuare normalmente.Come forzare un programma ad attendere fino al completamento di una richiesta HTTP in JavaScript?

Qualche idea?

Grazie in anticipo, Thanasis

+6

Mi piacerebbe che la gente avrebbe lasciato commenti esplicativi quando -1. – kojiro

risposta

10

È possibile eseguire una richiesta sincrona. jQuery esempio:

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

Si dovrebbe dare un'occhiata a jQuery di AJAX API. Consiglio vivamente di utilizzare un framework come jQuery per questa roba. Effettivamente fare ajax cross-browser è un vero dolore!

+0

questo è il modo migliore! Tuttavia, molte persone pensano che i framework JS siano malvagi e tendano a codificare tutto da soli. – Alex

+0

ho cercato di farlo con diversi modi utilizzando XmlHttpRequest per esempio, ma non ho trovare un modo in modo da fermare l'esecuzione fino a ottenere un rispondono .. –

+4

Alex, sono io! Sono uno di loro! ;) –

0

Per questo è possibile avviare il caricatore in javascript non appena la pagina inizia il caricamento e quindi è possibile chiuderlo quando termina la richiesta o il dom è pronto. Quello che sto cercando di dire, all'avvio del caricamento della pagina, avvia un caricatore. Quindi la pagina può eseguire più richieste sincrone utilizzando ajax, fino a quando, a meno che tu non abbia ricevuto risposta, non chiudere il loader vicino. Dopo aver ricevuto la risposta desiderata nella chiamata finale, è possibile chiudere il caricatore.

+1

si è fuori ... lui è chiedendo di bloccare più richieste. – Alex

+0

Sì, è esattamente quello che voglio fare .. –

+0

@Thanasis Petsas: Si prega di verificare il messaggio modificato. Spero che questo possa aiutarti. – Nik

2

È possibile utilizzare l'oggetto XMLHttpRequest per inviare la richiesta. una volta inviata la richiesta, è possibile eseguire la proprietà readyState per identificare lo stato. readyState seguirà diversi stati.

  • non inizializzato - non ha ancora iniziato il caricamento ancora
  • carico - sta caricando
  • interattivo - è stato caricato a sufficienza e l'utente può interagire con esso
  • completa - pieno carico

es:

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

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

spero che questo aiuterà

+0

Voglio che l'esecuzione del programma sia seriale e non voglio usare le callback. Voglio, se possibile, interrompere l'esecuzione del programma in "xmlhttp.send (null);" chiama e poi continua dopo che la richiesta è finita. –

+0

È possibile giocare con la proprietà readyState. Può essere che tu possa inserirlo nel ciclo while e così non andrà alla riga successiva fino al termine dell'esecuzione. Inoltre, se è possibile prevedere il tempo di esecuzione, è possibile utilizzare la funzione setTimeOut(). più su questa funzione puoi leggere qui. http://www.w3schools.com/jsref/met_win_settimeout.asp – Akie

0

Ho una situazione simile in un gioco costruito con Three.js e Google Closure. Devo caricare 2 risorse, Tre e Chiusura non mi permettono di renderle sincrone.

Inizialmente ho ingenuamente scritto quanto segue:

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 
    ... 
}; 

Il ciclo che attende i callback per completare non finisce mai, dal punto di vista del ciclo loaded non vengono mai incrementato. Il problema è che i callback non vengono attivati ​​fino al main resi (almeno su Chrome comunque).

Una soluzione potrebbe essere quella di avere entrambi i callback che controllano per vedere se è l'ultimo a completarsi, e loro proseguono per avviare il ciclo dell'animazione.

Un'altra soluzione - forse una risposta più diretta a ciò che si sta chiedendo (come ad aspettare per ogni carico prima di avviare un altro) - sarebbe quello di nido i callback come segue:

// 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

Ciao Argenti, benvenuto nello stackoverflow! Per favore, fai le tue risposte nel modo più chiaro possibile. Usa le parentesi graffe o avvolgi il tuo codice usando il carattere \ '. Se possibile, prova a vedere se è possibile ottenere qualcosa da eseguire prima di pubblicare. A queste domande si può fare riferimento anche in futuro, quindi per favore prova a fare lo sforzo! –

+0

ho trovato questo: Nota: _Starting con Gecko 30,0 (30,0 Firefox/Thunderbird 30.0/SeaMonkey 2.27), richieste sincrone sul thread principale sono stati deprecati a causa degli effetti negativi per l'experience._ utente [Mozilla Dev.Network] (https : //developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) –

18

C'è un terzo parametro a XmlHttpRequest :: open(), che ha lo scopo di indicare che si desidera la richiesta in modo asincrono (e quindi di gestire la risposta attraverso un gestore onreadystate).

Quindi, se si vuole che sia sincrona (cioè attendere la risposta), basta specificare false per questo terzo argomento. Si potrebbe anche voler impostare una proprietà di timeout limitato per la richiesta in questo caso, in quanto bloccherebbe la pagina fino alla ricezione.

Ecco un funzione di esempio all-in-one sia per la sincronizzazione e async:

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; 
} 

che si potrebbe chiamare in questo modo:

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

questo mi ha portato alla biblioteca asincrona, che rende questo straordinariamente semplice. https://github.com/caolan/async/ Non lasciatevi ingannare dal cruft della confezione. Devi solo includere un piccolo file javascript - async.js! – tudor