Tengo una clase, ChatRoom
, que solo se puede procesar después de recibir una solicitud HTTP de larga ejecución (podría tomar 1 segundo o 30 segundos). Entonces necesito retrasar el renderizado hasta que ChatRoom.json
no sea nulo.Retraso asincrónico de JS hasta que se cumpla una condición
En el siguiente código, estoy usando Closure Library's goog.async.ConditionalDelay
. Funciona, pero ¿hay una mejor manera (tal vez sin necesidad de Closure Library) para hacer esto?
ChatRoom.prototype.json = null; // received after a long-running HTTP request.
ChatRoom.prototype.render = function() {
var thisChatRoom = this;
function onReady() {
console.log("Received JSON", thisChatRoom.json);
// Do rendering...
}
function onFailure() {
alert('Sorry, an error occurred. The chat room couldn\'t open');
}
function isReady() {
if (thisChatRoom.json != null) {
return true;
}
console.log("Waiting for chat room JSON...");
return false;
}
// If there is a JSON request in progress, wait until it completes.
if (isReady()) {
onReady();
} else {
var delay = new goog.async.ConditionalDelay(isReady);
delay.onSuccess = onReady;
delay.onFailure = onFailure;
delay.start(500, 5000);
}
}
Nota que "si bien (JSON == null) {}" no es posible, porque eso sería síncrona (bloqueando todos los demás ejecución JS).
¿Por qué no utiliza la devolución de llamada de la solicitud HTTP? – SLaks
No puedo usar esa devolución de llamada porque se puede invocar el renderizado antes de que se devuelva el JSON, o 10 minutos después de que se devuelve. Básicamente, quiero poder invocar render() en cualquier momento que desee. –
Aún puede usar la devolución de llamada. En 'render', compruebe si se ha devuelto el JSON y, si no lo ha hecho, agréguelo a una matriz de devoluciones de llamada. O simplemente use los nuevos objetos Deferred de jQuery, que hace esto por usted. – SLaks