2015-10-12 2 views
41

Korzystanie z węzła 4.x. Kiedy masz Promise.all(promises).then(), jaki jest właściwy sposób, aby rozwiązać dane i przekazać je do następnego .then()?Objaśnienie obietnicy .all(). Then()?

chcę zrobić coś takiego:

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

Ale nie jestem pewien, w jaki sposób uzyskać dane do 2 .then(). Nie mogę użyć resolve(...) w pierwszym .then(). Pomyślałem, że mogę to zrobić:

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

Ale to nie wydaje się być właściwym sposobem na zrobienie tego ... Jakie jest właściwe podejście do tego?

Odpowiedz

65

Ale to nie wydaje się właściwy sposób to zrobić ..

To jest rzeczywiście właściwym sposobem, aby to zrobić (lub co najmniej się właściwy sposób to zrobić). Jest to kluczowy aspekt obietnic, są one potokiem, a dane mogą być masowane przez różne programy obsługi w przygotowaniu.

przykład:

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 obsługi pominięte dla zwięzłości w kodzie produkcji zawsze albo propagacji obiecujące, lub uchwyt odrzucenie).

wyjście, które widzimy, to:

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

... bo pierwsza obsługi dostaje rozdzielczość dwóch obietnic (1 i 2) jako tablicę, a następnie tworzy nową tablicę z każdego z tych pomnożyć przez 10 i zwraca go. Drugi przewodnik otrzymuje to, co zwrócił pierwszy handler.

Jeżeli dodatkowa praca robisz jest synchroniczny, można także umieścić go w pierwszy Handler:

Przykład:

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; 
 
    });

... ale jeśli jest to asynchroniczne, nie będziesz chciał tego robić, ponieważ kończy się to zagnieżdżaniem, a zagnieżdżenie szybko wymknie się spod kontroli.

+1

Interesujące. Dziękuję Ci. Czy nie można "odrzucić" wartości po początkowej funkcji "Obietnica"? Lub rzucenie błędu w dowolnym miejscu łańcucha zabierze Cię do '.catch()'? Jeśli tak jest, jaki jest sens "odrzucenia" w pierwszej kolejności? Dlaczego nie po prostu rzucić błąd? Jeszcze raz dziękuję, –

+3

@JakeWilson: To są różne pytania. Ale mylicie dwie oddzielne rzeczy: * Tworzenie * i ustalanie obietnicy oraz * postępowanie * z obietnicą. Kiedy tworzysz i rozliczasz obietnicę, używasz 'resolve' i' reject'. Kiedy * obsługujesz *, jeśli przetwarzanie nie powiedzie się, rzeczywiście rzucasz wyjątek, aby wywołać ścieżkę niepowodzenia.I tak, możesz także wyrzucić wyjątek z oryginalnego callback'u 'Promise' (zamiast używać' reject'), ale nie wszystkie niepowodzenia są wyjątkami. –

+0

Dobrze wyjaśnione. Jeszcze raz dziękuję –