2015-10-12 12 views
41

Utilizzo del nodo 4.x. Quando hai un Promise.all(promises).then() qual è il modo corretto per risolvere i dati e passarlo al prossimo .then()?Promise.all(). Then() risolto?

voglio fare qualcosa di simile:

Promise.all(promises).then(function(data){ 
    // Do something with the data here 
}).then(function(data){ 
    // Do more stuff here 
}); 

ma non sono sicuro di come ottenere i dati per il 2 ° .then(). Non riesco a utilizzare resolve(...) nel primo .then(). Ho capito che posso fare questo:

return Promise.all(promises).then(function(data){ 
    // Do something with the data here 
    return data; 
}).then(function(data){ 
    // Do more stuff here 
}); 

Ma questo non sembra il modo corretto per farlo ... Qual è l'approccio giusto per questo?

risposta

65

Ma questo non sembra il modo corretto di farlo ..

Questo è davvero il modo corretto di farlo (o almeno un modo corretto per farlo). Questo è un aspetto chiave delle promesse, sono una pipeline e i dati possono essere massaggiati dai vari gestori nella pipeline.

Esempio:

const promises = [ 
 
    new Promise(resolve => setTimeout(resolve, 0, 1)), 
 
    new Promise(resolve => setTimeout(resolve, 0, 2)) 
 
]; 
 
Promise.all(promises) 
 
    .then(data => { 
 
    console.log("First handler", data); 
 
    return data.map(entry => entry * 10); 
 
    }) 
 
    .then(data => { 
 
    console.log("Second handler", data); 
 
    });

(. catch gestore omessi per brevità nel codice di produzione, sempre sia propagare la promessa, o gestire il rifiuto.)

L' l'output che vediamo è:

 
First handler [1,2] 
Second handler [10,20] 

... perché il primo gestore ottiene la risoluzione delle due promesse (1 e 2) come una matrice, e quindi crea un nuovo array con ciascuno di quelli moltiplicato per 10 e lo restituisce. Il secondo gestore ottiene ciò che il primo gestore ha restituito.

Se il lavoro in più che stai facendo è sincrono, si può anche mettere esso nel il primo gestore:

Esempio:

const promises = [ 
 
    new Promise(resolve => setTimeout(resolve, 0, 1)), 
 
    new Promise(resolve => setTimeout(resolve, 0, 2)) 
 
]; 
 
Promise.all(promises) 
 
    .then(data => { 
 
    console.log("Initial data", data); 
 
    data = data.map(entry => entry * 10); 
 
    console.log("Updated data", data); 
 
    return data; 
 
    });

... ma se è asincrono, non vorrai farlo mentre finisce per essere annidato, e l'annidamento può rapidamente sfuggire di mano.

+1

Interessante. Grazie. Quindi non è possibile "rifiutare" un valore dopo la funzione iniziale "Promise"? O lanciare un errore in qualsiasi punto della catena ti porta al '.catch()'? Se questo è il caso, qual è il punto di "rifiutare" in primo luogo? Perché non basta lanciare un errore? Grazie ancora, –

+3

@JakeWilson: Queste sono domande diverse. Ma stai confondendo due cose separate: * Creare * e sistemare la promessa e * gestire * la promessa. Quando crei e stabilisci la promessa, usi 'resolve' e' reject'. Quando si * gestisce *, se l'elaborazione fallisce, si lancia in effetti un'eccezione per attivare il percorso dell'errore.E sì, puoi anche lanciare un'eccezione dal callback 'Promise' originale (piuttosto che usare' reject'), ma non tutti i guasti sono eccezioni. –

+0

Ben spiegato. Grazie ancora –

Problemi correlati