2012-09-04 10 views
7

Todavía estoy tratando de entender lo que sucede con los objetos Deferred de JQuery, y me estoy rascando la cabeza ante un problema en particular. En el siguiente código, inicialmente intenté encadenar deferred.then() pero nunca funcionó. Las tres funciones se ejecutan a la vez. Solo después de que mi compañero de trabajo me indicara la función pipe, las cosas se pusieron en su lugar. La pregunta es, ¿por qué funciona pipe(), pero no then()?

var otherDefer = function(msg){return function(){return testDefer(msg)}}; 
var there = otherDefer("there,"); 
var guy = otherDefer("guy.");      

function testDefer(msg) { 
    var deferred = $.Deferred(); 
    pretendAjaxCall(function() { 
     $('<li>'+msg+'</li>').appendTo('#msgOut'); 
     deferred.resolve(); 
    }); 
    return deferred.promise(); 
} 

function pretendAjaxCall(callback) { 
    setTimeout(callback,1500); 
} 

$.when(testDefer("Hi")).pipe(there).then(guy);​ 

También probé return deferredreturn deferred.promise() en lugar de cuando se utiliza when().then().then().

jsFiddle de código anterior: http://jsfiddle.net/eterpstra/yGu2d/

+0

El violín funciona bien para mí usando "then(). Then()" (Chrome). – devundef

+0

de la forma en que lo entiendo, '.then' devuelve el objeto diferido original, lo que permite otras llamadas que luego, hecho, fallido, etc. '.pipe' filtra el resultado y puede devolver una nueva promesa/diferida y cualquier función posterior, dones, falla en la cadena actuará sobre ese objeto en lugar del original. – MrOBrian

+0

esta respuesta anterior es para Jquery 1.8 y siguientes, lea a continuación las respuestas –

Respuesta

5

Esta es la forma en then() y pipe() trabajo en su muestra:

then() vuelve diferidos y llamando then() en este mismadiferido que sólo tiene que añadir una segunda devolución de llamada a la misma que se llamará simultáneamente con el primero

pipe(), en su lugar, devuelve nuevoPromise que le permite construir una cadena y es por eso que se obtiene secuenciales pide, en este caso


Tome un vistazo a los siguientes recursos para obtener más información sobre la tubería/entonces:

When should I use jQuery deferred's "then" method and when should I use the "pipe" method?

Promise Pipelines in JavaScript

+0

El artículo "Promesa de tuberías en JavaScript" fue muy útil. ¡Gracias! – eterps

2

Estás usando .then de una manera que no se supone que se utilizará - usted está discutiendo un diferido a ella, cuando all that .then expects is a plain function to be added as a callback.

El método .then devuelve el original Diferido, que ya se ha resuelto. Cuando se resuelve Deferred, todas las devoluciones de llamadas agregadas con .then se ejecutan inmediatamente.

Por otro lado, la función .pipe toma un conjunto de funciones, o una promesa (que es lo que está enviando) y se resuelve en función del estado del original diferido. ¡La funcionalidad de .pipe es en realidad lo que estás buscando!

6

Desde jQuery 1.8 a continuación,() devuelve un nuevo Promise (el mismo que el tubo()) en lugar del mismo diferido que cuando() vuelve.

cambiar la versión de jQuery a 1.8.3 o superior en su ejemplo en:

http://jsfiddle.net/eterpstra/yGu2d

y

$.when(testDefer("Hi")).then(there).then(guy);

va a funcionar.

+0

En el momento en que se hizo esta pregunta, [jQuery 1.8 todavía era bastante nuevo] (http://blog.jquery.com/2012/08/09/jquery-1-8-released/), que es probablemente la razón por la cual ninguno de los respuestas antiguas sugieren actualización. Aún así, es bueno tener una actualización para los futuros usuarios que enfrentan este problema para que no comiencen a usar las funciones obsoletas en el nuevo código. –

Cuestiones relacionadas