2011-05-30 50 views
20

Inmediatamente después de que mi script esté cargado, estoy haciendo una solicitud de Ajax para obtener algunas traducciones. Esto siempre debe regresar después de que el documento esté listo, ya que estoy cargando mis scripts en la parte inferior de la página, pero aún tengo curiosidad de si sería posible obtener un Deferred Object en el estado listo para documentos.¿Puedo obtener un jQuery aplazado en document.ready()?

De esa manera, sería posible asegurarse de que tanto el documento esté listo como la llamada Ajax devuelta con éxito antes de hacer cualquier otra cosa, p. de esta manera:

$.when($.ajax('translations'), document.ready()) 
.then(function(){ 
    // Start doing stuff here 
}); 

Respuesta

22

Puede asociar un objeto diferido con el documento usando data() y resolve() en su manejador ready. De esta manera, usted debe ser capaz de utilizar el objeto diferido almacenado con $.when():

$(document).data("readyDeferred", $.Deferred()).ready(function() { 
    $(document).data("readyDeferred").resolve(); 
}); 

$.when($.ajax("translations"), $(document).data("readyDeferred")) 
.then(function() { 
    // Start doing stuff here. 
}); 
+0

Gracias, sencillo y directo. Eso probablemente también funcione con una variable global o algo similar. – Daff

+1

@Daff, absolutamente.Personalmente prefiero usar 'data()' en lugar de una variable global porque es más flexible y evita contaminar el espacio de nombres global. –

+6

nota pedante. No hay razón para almacenar la variable en absoluto. Solo lo necesita durante la fase de configuración, por lo tanto, use scope de cierre: '(function() {var diferido = new $. Diferido(); $ (function() {deferred.resolve();}); $ .when ($. ajax ('foo'), diferido) .then (function() {});})(); '... Si usa telescopios locales, no es necesario almacenarlos, solo deje que los cierres lo vinculen por usted. – ircmaxell

18

Aquí hay una versión limpia del comentario de ircmaxell:

(function() { 
    var doc_ready = $.Deferred(); 
    $(doc_ready.resolve); 
    $.when(doc_ready, $.ajax('translations')).then(function() { 
    console.log("done"); 
    }); 
})(); 

edición

algunas aclaraciones para detener las ediciones incorrectas:

Pasar una función al objeto jquery (por ejemplo, $(some_func)) es lo mismo que $(document).ready(some_func).

Por lo tanto, la línea $(doc_ready.resolve); es la abreviatura de algo como esto:

$(document).ready(function() { 
    doc_ready.resolve() 
}); 
6

Mi versión es:

$.when(
    $.Deferred(function() { $(this.resolve); }), 
    $.ajax('translations')). 
    then(function() { console.log("done"); }); 
+1

Me gusta la forma en que se contiene el diferido. Una sugerencia sería cambiar el orden de tus diferidos, de modo que el primer argumento de la función de devolución de llamada sea cualquier valor que se haya resuelto para el $ .ajax diferido. – Asaf

9

Prueba esto:

$.when($.ajax('translations'), $.ready).then(function() { 
    // Start doing stuff here 
}); 
+0

¿Está esto documentado? – Eric

+3

Tenga en cuenta que '$ .ready' no es de hecho diferido, pero pasa a tener un método' promesa' de todos modos. – Eric

+1

No, aún no está documentado: https://github.com/jquery/api.jquery.com/issues/205 – thorn

2

Actualización de referencia (2015):

Este servicio está disponible en las versiones actuales de jQuery:

$.when($.ready).then(...); 

También es sencilla para la conversión de una corriente usando highlandjs:

_($.when($.ready)).map(transform).pipe(output) // etc. 
+0

Como se mencionó anteriormente, no está documentado que $ .ready sea un objeto similar diferido. Esto aún no está documentado en 2016. –

0

de jQuery when no es una promesa adecuada. Puede forzar en uno como este:

function documentReady() { 
    return Promise.resolve($.when($.ready)); 
} 

Uso:

documentReady().then(function($) { ... }); 

Le pasa a resolver con $ por lo que es una especie de conveniente también.

aplicación alternativa:

function documentReady() { 
    return new Promise(r => $(r)); 
} 
Cuestiones relacionadas