2013-11-23 21 views
5

Ho il seguente codice:Come accedere ai risultati della promessa precedente nella catena di offerte di AngularJS?

authService.authenticate() 
.then(function (user) { 
    return Task.all({user: user}) 
}) 
.then(function (tasks) { 
    // How to access user object here? 
}) 

C'è qualche modo incorporato per passare user oggetto per la seconda funzione then senza fare qualcosa di simile:

var user2 = null; 
authService.authenticate() 
.then(function (user) { 
    user2 = user 
    return Task.all({user: user}) 
}) 
.then(function (tasks) { 
    // Use user2 here 
}) 

o questo:

authService.authenticate() 
.then(function (user) { 
    var defer = $q.defer() 
    Task.all({user: user}).then(function (tasks) { 
    return defer.resolve(user, tasks) 
    }) 
    return defer.promise 
}) 
.then(function (user, tasks) { 
    // Use user2 here 
}) 

o annidandoli chiamando il secondo then direttamente su Task.all (in questo modo avrei l'oggetto user disponibile tramite chiusura)? Annidarli è esattamente quello che sto cercando di evitare.

risposta

2

si può mettere l'allora nell'ambito di applicazione dove l'utente è ancora accessibile (verificare chiusure)

authService.authenticate() 
.then(function (user) { 
    Task.all({user: user}) 
    .then(function (tasks) { 
    // How to access user object here? 
    }) 
}) 

Da Kriskowal di Q documentation stesso, entrambi gli stili sono equivalenti. Angular's $q è basato su Q

L'unica differenza è la nidificazione. È utile annidare i gestori se è necessario acquisire più valori di input nella chiusura.

+0

Grazie, ma questo è il terzo caso di cui parlavo nella mia interrogazione - nidificazione loro :) Sto cercando di evitarlo, perché ho appena mostrato un caso semplificato - nel codice reale ci sono ancora alcune promesse, quindi nidificarle sarebbe come usare i callback. – szimek

+0

hmm ... sì, hai ragione. Il fatto è che sto usando questo stile nidificato nel mio codice, e il codice è davvero molto grande ... Il livello di nidificazione non è davvero così grande. Inoltre, la sintassi Coffeescript aiuta molto;) –

+0

Sto usando anche CoffeeScript, quindi proverò ad annidarli e vedere come appare. Anche se non sono esattamente sicuro di come funziona la gestione degli errori in caso di promesse nidificate ... gli errori di – szimek

1

potesse unire utente e le attività in un unico oggetto da passare al prossimo then

authService.authenticate() 
.then(function (user) { 
    var defer = $q.defer() 
    Task.all({user: user}).then(function (tasks) { 

    return defer.resolve({user:user, tasks:tasks}) 
    }) 
    return defer.promise 
}) 
.then(function (data) { 
    $scope.user=data.user; 
    $scope.tasks=data.tasks; 
}) 

DEMO

+0

Grazie! Questo è quello che sto facendo nel secondo esempio, anche se solo dopo averlo postato, ho scoperto che posso passare solo un singolo argomento a 'defer.resolve', quindi il mio esempio con' defer.resolve (user, tasks) 'è leggermente errato. Sembra essere la soluzione più pulita per me, sebbene richieda la creazione manuale di un nuovo oggetto posticipo, che può risultare molto utile se è necessario ad es. passare una variabile attraverso l'intera catena. – szimek

+0

potrebbe memorizzare vari passaggi in un oggetto servizio, restituire l'oggetto alla fine – charlietfl

+0

Non ho familiarità con le promesse Q/Angular, ma se 'Task' accade in modo asincrono, garantisce che' defer' conterrà sia 'user' e i dati 'tasks' per il momento in cui si verifica il secondo corpo' then'? Se capisco correttamente, 'defer.resolve()' sta mutando lo stato dell'oggetto 'defer', quindi come fa restituire' defer.promise' sapere se il 'Task.all' o il corpo sono terminati? Sto cercando di capire come funziona questa soluzione. –

Problemi correlati