2012-04-20 15 views
18

Ho letto di differite e promesse in jQuery ma non l'ho ancora usato.Informazioni su Deferred.pipe()

Ho capito tutto molto bene ma il metodo pipe. Non ho davvero capito di cosa si tratta.

Alcuni potrebbero aiutarmi a capire cosa fa e dove potrebbe essere utilizzato?

So che c'è una domanda intitolata esattamente come questa (here) ma non è la stessa cosa. Sto chiedendo aiuto per capirlo e qualche esempio. L'obiettivo dell'altra domanda è capire perché non funziona in un caso particolare.

+1

Avete controllato http://api.jquery.com/deferred.pipe/? – Armatus

+1

Sì, sì. Ho iniziato da lì. – Diego

+0

Si noti che 'deferred.pipe' e' deferred.when' sono equivalenti dalla v1.8 (consultare http://stackoverflow.com/questions/12011925/pipe-and-then-documentation-vs-reality-in-jquery- 1-8) – tokland

risposta

46

Fondamentalmente, Deferred.pipe() è un equivalente asincrono a $.map(). Proietta nuovi valori da altri valori forniti come input, ma il suo scopo deve essere utilizzato con continuazioni.

Iniziamo con un esempio che richiede solo $.each() ed emette una richiesta AJAX che restituisce un oggetto semplice. Per ogni proprietà di questo oggetto, vogliamo il controllo del modulo il cui attributo id è la chiave della proprietà per impostarne il valore sul valore della proprietà.Possiamo scrivere qualcosa del tipo:

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

Ora diciamo che vogliamo applicare qualche funzione ai valori prima di aggiornare i controlli del modulo. Se lo facciamo a livello locale, dobbiamo solo scrivere:

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

Ma cosa succede se doSomethingWith() non è implementata sul lato client, ma lato server attraverso un altro servizio web? In tal caso, vogliamo concatenare il flusso di controllo nella seconda richiesta AJAX e aggiornare solo i controlli del modulo quando viene restituita la seconda richiesta. Deferred.pipe() rende così facile:

$.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

Ottima risposta !! Grazie! – Diego

+0

Questi 2 esempi sono in realtà funzionalmente uguali? Questa idea che la funzione anon che chiama il webservice all'interno della chiamata '.pipe', * iterativamente *, è nuova per me. So che a partire da jQuery 1.8, il metodo '.pipe' è deprecato e sostituito da' .then', ma potresti approfondire le differenze funzionali tra la versione '.each' e' .pipe', se esistono? In che modo i dati di ritorno dal primo GET sono enumerati da '.pipe'? Se questo non è il modo in cui funziona, penso che sarebbe utile chiarire che la versione '.pipe' che chiama un webservice funziona come un processo batch, non in modo iterativo. – JoeBrockhaus

+0

@Joe, gli esempi sono "funzionalmente" uguali, solo il primo elabora i valori in modo sincrono, mentre il secondo lo fa in modo asincrono (attraverso un servizio web). 'pipe()' (e ora 'then()') viene chiamato solo quando viene restituita la prima richiesta, quindi i dati originali sono già disponibili. Il codice * sembra * iterativo, ma 'pipe()' restituendo una promessa significa che il resto della pipeline attenderà che tale promessa sia soddisfatta (o respinta). –

1

Hiya è questo ciò che si sta cercando :)

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

citazione metodo

Il tubo() fornisce un filtro sia per il successo e mancata risoluzione (della richiesta AJAX). Se la risoluzione originale è riuscita, il filtro pipe() passa una risposta con esito positivo attraverso; oppure, modifica la risoluzione, restituendo una nuova promessa rifiutata. Quindi, se la richiesta originale era un fallimento, che sarebbe davvero inaspettato nella nostra API, il filtro pipe() passa semplicemente attraverso una struttura di risposta normalizzata API .... collegamento

Stack con esempioUnderstanding jQuery Deferred.pipe() (contiene jsfiddle)

Informazioni differite & Promesso? vedere quihttp://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/

pagina Jquery ufficiale APIhttp://api.jquery.com/deferred.pipe/ (con esempi)

Descrizione: metodo di utilità per filtrare Deferreds e/o catene.

Il metodo deferred.pipe() restituisce una nuova promessa che filtra lo stato e i valori di un rinvio tramite una funzione. Le funzioni doneFilter e failFilter filtrano lo stato e i valori respinti/differiti respinti differiti originali. A partire da jQuery 1.7, il metodo accetta anche una funzione progressFilter per filtrare eventuali chiamate ai metodi di notifica differita o notifyWith originali di .

11

OK, vedo un sacco di materiale di riferimento in un'altra risposta qui, ma la lettura a volte non è lo stesso di comprensione.

Trovo più semplice pensare a una Promessa e all'applicazione di .done() a essa rispetto a .pipe(). Ognuno agisce in modo diverso. Se prendo promessa.done (funzione (risultato) {...}), allora posso aggiungere più .done() o .fail() dopo questo perché ogni chiamata a .done() o .fail () restituisce la stessa identica promessa. Quindi ogni funzione sarà legata alla promessa originale e se verrà risolta o respinta.

Ora, contrariamente a .pipe(). Se prendo promise.pipe (function (result) {...}), allora quello che esce da .pipe() è una promessa tutta nuova! Se poi aggiungo .done() o .fail() a quella promessa, quelle funzioni otterranno la versione modificata dei risultati restituita da .pipe(), non i risultati originali.

Così .pipe() è, nella mia esperienza, raramente necessario. L'unica volta che è davvero utile è se è necessario modificare i dati restituiti da una promessa prima che il codice venga visualizzato da altri (ad esempio, modificare alcuni risultati di una chiamata AJAX sul lato client prima che qualsiasi altro codice lato client funzioni con it) o ​​se hai bisogno di sequenziare le cose. Ad esempio, dopo la promessa A risolve o rifiuta, intraprende un'altra azione, e solo quando ciò è fatto, vogliamo che l'altro codice si attivi infine. Tutto l'altro codice è allegato alla promessa B proveniente dalla chiamata .pipe().

Ecco una domanda recente in cui un altro utente ha avuto problemi con l'uso di promises e .pipe() /. Done() /. When() e ho provato a fornire del codice per chiarire l'uso di ciascuno in un jsFiddle : Do something when all deferreds are resolved

+1

Ottima risposta, esattamente quello che ero provando t o capire perché usare .pipe() invece di .done(). – uglymunky