2012-04-20 13 views
18

He estado leyendo sobre diferimientos y promesas en jQuery pero aún no lo he usado.Entender Deferred.pipe()

He entendido todo muy bien, pero el método de tubería. Realmente no entendí lo que es.

¿Podrían algunos ayudarme a entender lo que hace y dónde podría usarse?

Sé que hay una pregunta con el mismo nombre (here) pero no es lo mismo. Estoy pidiendo ayuda para entenderlo y algunos ejemplos. El objetivo de la otra pregunta es averiguar por qué no funciona en un caso particular.

+1

¿Ha comprobado http://api.jquery.com/deferred.pipe/? – Armatus

+1

Sí, lo he hecho. Empecé desde allí. – Diego

+0

Tenga en cuenta que 'deferred.pipe' y' deferred.when' son equivalentes desde v1.8 (vea http://stackoverflow.com/questions/12011925/pipe-and-then-documentation-vs-reality-in-jquery- 1-8) – tokland

Respuesta

46

Básicamente, Deferred.pipe() es un equivalente asíncrono a $.map(). Proyecta nuevos valores a partir de otros valores proporcionados como entrada, pero su propósito es ser utilizado con continuaciones.

Comencemos con un ejemplo que solo requiere $.each() y emite una solicitud AJAX que devuelve un objeto simple. Para cada propiedad de este objeto, queremos que el control de formulario cuyo atributo id sea la clave de la propiedad establezca su valor en el valor de la propiedad.Podemos escribir algo como:

$.ajax("your/url", { 
    dataType: "json" 
}).done(function(data) { 
    $.each(data, function(key, value) { 
     $("#" + key).val(value); 
    }); 
}); 

Ahora digamos que queremos aplicar alguna función a los valores antes de actualizar los controles de formulario. Si lo hacemos a nivel local, sólo tenemos que escribir:

$.ajax("your/url", { 
    dataType: "json" 
}).done(function(data) { 
    $.each(data, function(key, value) { 
     // doSomethingWith() projects values synchronously, as map() does. 
     $("#" + key).val(doSomethingWith(value)); 
    }); 
}); 

Pero qué sucede si doSomethingWith() no está implementado en el cliente, pero del lado del servidor a través de otro servicio web? En ese caso, queremos encadenar el flujo de control en la segunda solicitud de AJAX y solo actualizar los controles de formulario cuando haya regresado la segunda solicitud. Deferred.pipe() hace tan fácil:

$.ajax("your/url", { 
    dataType: "json" 
}).pipe(function(theOriginalData) { 
    return $.ajax("your/web/service/doSomethingWith", { 
     data: theOriginalData, 
     dataType: "json" 
    }); 
}).done(function(theFinalData) { 
    $.each(theFinalData, function(key, value) { 
     $("#" + key).val(value); 
    }); 
}); 
+2

¡¡Gran respuesta !! ¡Gracias! – Diego

+0

¿Estos 2 ejemplos son funcionalmente iguales? Esta noción de que la función anon que llama al servicio web dentro de la llamada '.pipe', * iterativamente *, es nueva para mí. Sé que a partir de jQuery 1.8, el método '.pipe' está en desuso y reemplazado por' .then', pero ¿podría profundizar en las diferencias funcionales entre la versión '.each' y' .pipe', si existen? ¿Cómo son los datos de retorno del primer GET enumerado por '.pipe'? Si esta no es la forma en que funciona, creo que sería útil dejar en claro que la versión '.pipe' que llama a un servicio web funciona como un proceso por lotes, no de forma iterativa. – JoeBrockhaus

+0

@Joe, los ejemplos son "funcionalmente" lo mismo, solo el primero procesa los valores de forma síncrona, mientras que el segundo lo hace de forma asincrónica (a través de un servicio web). 'pipe()' (y ahora 'then()') solo se llama cuando ha regresado la primera solicitud, por lo que los datos originales ya están disponibles. El código * parece * iterativo, pero 'pipe()' devuelve una promesa significa que el resto de la tubería esperará a que se cumpla (o rechace) esa promesa. –

1

Hiya es esto lo que está buscando :)

[agradable lecturas] http://www.bennadel.com/blog/2255-Using-jQuery-s-Pipe-Method-To-Change-Deferred-Resolution.htm

cita método

El tubo() proporciona un filtro tanto para el éxito y falla resoluciones (de la solicitud AJAX). Si la resolución original es exitosa, el filtro de tubería (o) pasa una respuesta realmente exitosa ; o, cambia la resolución y devuelve una nueva promesa rechazada . Entonces, si la solicitud original fue un fracaso, lo que sería verdaderamente inesperado en nuestra API, el filtro de la tubería() simplemente pasa a través de una estructura de respuesta API normalizada .... enlace

Pila con ejemploUnderstanding jQuery Deferred.pipe() (tiene jsfiddle en él)

Understanding Deferred & Promise? por favor ver aquíhttp://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/

página oficial Jquery APIhttp://api.jquery.com/deferred.pipe/ (con ejemplos)

Descripción: método de utilidad para filtrar Deferreds y/o de cadena.

El método deferred.pipe() devuelve una nueva promesa que filtra el estado y los valores de un diferido a través de una función. Las funciones failFilter doneFilter y filtran el estado y los valores rechazados resueltos/ del diferido original. A partir de jQuery 1.7, el método también acepta una función progressFilter para filtrar las llamadas al diferido notificar o notificar con métodos.

11

OK, veo una gran cantidad de material de referencia en otra respuesta aquí, pero la lectura a veces no es lo mismo que comprender.

Me resulta más fácil pensar en una promesa y la aplicación de .done() a ella frente a .pipe() a la misma. Cada uno actúa de manera diferente. Si tomo promise.done (function (result) {...}) entonces puedo agregar más .done() 's o .fail()' s después de eso porque cada llamada a .done() o .fail () devuelve exactamente la misma promesa. Entonces, cada función estará ligada a la promesa original y si se resuelve o rechaza.

Ahora, contraste eso con .pipe(). Si tomo promise.pipe (function (result) {...}), ¡lo que sale de .pipe() es una nueva promesa! Si luego adjunto .done() o .fail() a esa promesa, esas funciones obtendrán la versión modificada de los resultados que devuelve .pipe(), no los resultados originales.

So .pipe() es, en mi experiencia, rara vez es necesario. El único momento en que realmente es útil es si necesita modificar los datos que se devuelven de una promesa antes de que lo vea otro código (por ejemplo, modificar algunos resultados de una llamada AJAX en el lado del cliente antes de que funcione cualquier otro código del lado del cliente).) o si necesita secuenciar cosas. Por ejemplo, después de que la promesa A resuelve o rechaza, realiza otra acción, y solo cuando eso se hace queremos que otro código finalmente se active. Todo el otro código se adjunta a la promesa B que vino de la llamada .pipe().

Aquí hay una pregunta reciente en la que otro usuario tuvo problemas con el uso de promesas y .pipe() /. Done() /. When() y traté de proporcionar algún código para aclarar el uso de cada uno en jsFiddle : Do something when all deferreds are resolved

+1

Gran respuesta, exactamente lo que era intentando t o averiguar por qué wrt .pipe() en lugar de .done(). – uglymunky