2012-09-04 13 views
7

Sto ancora cercando di riprendermi usando gli oggetti Deferred di JQuery, e sto grattando la testa per un problema particolare. Nel codice seguente, inizialmente ho provato a concatenare deferred.then() ma non ha mai funzionato. Tutte e tre le funzioni vengono eseguite contemporaneamente. Solo dopo che il mio collega di lavoro mi ha indicato la funzione , le cose sono andate a posto. La domanda è, perché funziona pipe() ma non 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);​ 

Ho anche provato return deferred anziché return deferred.promise() utilizzando when().then().then().

jsFiddle per il codice di cui sopra: http://jsfiddle.net/eterpstra/yGu2d/

+0

Il violino funziona bene per me utilizzando "then(). Then()" (Chrome). – devundef

+0

nel modo in cui lo capisco, '.then' restituisce l'oggetto posticipato originale, consentendo altre chiamate, quindi, fallite, ecc. '.pipe' filtra il risultato e può restituire un nuovo posticipo/promessa e ogni successivo thens, dones, fail nella catena agirà su quell'oggetto piuttosto che sull'originale. – MrOBrian

+0

questa risposta sopra è per Jquery 1.8 e sotto, leggi sotto le risposte –

risposta

5

Questo è il modo in then() e pipe() lavoro nel campione:

then() rendimenti differite e chiamando then() su questo stessodifferite è sufficiente aggiungere un secondo callback ad essa che si chiamerà contemporaneamente con il primo

pipe(), restituisce invece nuovoPromessa che consente di costruire una catena ed è per questo che si ottiene sequenziali chiamate in questo caso


Date un'occhiata alle seguenti risorse per ulteriori informazioni su tubo/allora:

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

Promise Pipelines in JavaScript

+0

L'articolo "Promise Pipelines in JavaScript" è stato super utile. Grazie! – eterps

2

Stai utilizzando .then in un certo senso non dovrebbe essere usato - tu sei sostenendo una differita ad esso, quando all that .then expects is a plain function to be added as a callback.

Il metodo .then restituisce il Deferred originale, che è già stato risolto. Quando il Differito si risolve, tutti i callback aggiunti con .then vengono eseguiti immediatamente.

D'altra parte, la funzione .pipe accetta un insieme di funzioni o una Promessa (che è ciò che si sta inviando) e si risolve in base allo stato del rinviato originale. La funzionalità di .pipe è in realtà ciò che stai cercando!

6

da jQuery 1.8 allora() restituisce una nuova promessa (lo stesso tubo()) in costante dello stesso Differito che quando() ritorna.

cambiare la versione jQuery per 1.8.3 o superiore nel tuo esempio a:

http://jsfiddle.net/eterpstra/yGu2d

e

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

funzionerà.

+0

Al momento della domanda, [jQuery 1.8 era ancora abbastanza nuovo] (http://blog.jquery.com/2012/08/09/jquery-1-8-released/) che probabilmente è il motivo per cui nessuno dei le risposte più vecchie suggeriscono l'aggiornamento. Tuttavia, è utile disporre di un aggiornamento per i futuri utenti che affrontano questo problema, in modo che non inizino a utilizzare funzioni obsolete nel nuovo codice. –

Problemi correlati