2015-12-12 4 views
5

wszystko:Jak zdecydować, które obietnica robi potem/catch według

Jestem całkiem nowy, Obiecaj, oto przykład:

var someAsyncThing = function() { 
    return new Promise(function(resolve, reject) { 
    // this will throw, x does not exist 
    resolve(x + 2); 
    }); 
}; 

var someOtherAsyncThing = function() { 
    return new Promise(function(resolve, reject) { 
    reject('something went wrong'); 
    }); 
}; 

someAsyncThing().then(function() { 
    return someOtherAsyncThing(); 
}).catch(function(error) { 
    console.log('oh no', error); 
}); 

Nie dość dostać jak .then() działa z Promise, teraz mogę zrozumieć someAsyncThing() zwrócenie obietnicy, która wygeneruje wyjątek i tym samym przejdzie do części .catch(). A jeśli możemy zmienić resolve(x+2) do resolve(4), a następnie będzie go uruchomić someOtherAsyncThing(); i wrócić inną obietnicę

pierwsze pytanie brzmi, czy powrót .Następnie() jest ta obietnica?

I drugie pytanie, jeśli w someOtherAsyncThing() „s Obietnicy, używam resolve(x+2) spowodować wyjątek, to będzie również udać się do samego .catch() częściową jak mogę sprawić, że .catch() tylko złapać wyjątek spowodowane someAsyncThing() obietnica (i to samo pytanie dla przykuty .then(), jeśli istnieje)?

Dzięki

+0

Połów złapie każdy wyjątek w łańcuchu, aby uzyskać bardziej szczegółowe informacje na temat wyjątku lub zrobić coś innego, w zależności od tego, która obietnica wyrzuci wyjątek, który musiałbyś odrzucić z informacją, którą następnie będziesz obsługiwał w bloku catch. – PixMach

+0

@PixMach Dzięki, rozumiem. Jest to bardzo elastyczne i trudne w obsłudze. – Kuan

Odpowiedz

3

pierwsze pytanie brzmi, czy powrót .Następnie() jest ta obietnica?

p.then() zwraca obietnicę - zawsze. Jeśli wywołanie zwrotne przekazane do handler'a .then() zwróci wartość, to nowo zwrócona obietnica zostanie rozstrzygnięta w tym samym czasie, co obietnica nadrzędna, ale zostanie rozwiązana z zwróconą wartością z procedury obsługi.

Jeśli handler .then() zwraca obietnicę, to obietnica zwrócona przez .then() nie zostanie spełniona/odrzucona, dopóki obietnica zwrócona przez handler'a nie zostanie wypełniona/odrzucona. Są połączeni ze sobą.

Jeśli zostanie wysłany nośnik .then(), obietnica zwrócona przez .then() jest odrzucona z wyjątkiem jako wartość. Rzucanie jest tym samym, co zwrot odrzuconej obietnicy.

jeśli w someOtherAsyncThing() „s Obietnicy, używam resolve(x+2) spowodować wyjątek, to będzie również udać się do samego .catch() części, to jak mogę sprawić, że .catch() Jedynym wyjątkiem catch spowodowane someAsyncThing()” s obietnicy (i to samo pytanie dla przykuty .then() jeśli jest jakiś)?

Piękno obietnic polega na tym, że błędy rozprzestrzeniają się w łańcuchu aż do przetworzenia. Sposób, w jaki powstrzymujesz propagację błędu na dowolnym poziomie, polega na obsłudze tego błędu.

Jeśli chcesz oddzielić możliwości .catch(), musisz po prostu złapać na niższym poziomie. Na przykład:

someAsyncThing().then(function() { 
    return someOtherAsyncThing().catch(function(err) { 
     // someOtherAsyncThing rejected here 
     // you can handle that rejection here and decide how you want to proceed 

     // for example, suppose you just want to handle the rejection, log it 
     // and then continue on as if there was no problem, you can just return 
     // a value here 
     return 0; 
    }); 
}).catch(function(error) { 
    console.log('oh no', error); 
}); 
+0

Dzięki, rozumiem. Jest to bardzo elastyczne i trudne do zrozumienia. Czy masz jakieś linki, które mówią o Obietnicy, a następnie() bardzo łatwe do zrozumienia? – Kuan

+0

@Kuan - Nie mam ulubionego odniesienia. Wygląda na to, że obejmuje to całkiem dobrze: http://trevorburnham.com/presentations/flow-control-with-promises/#/. Jeśli po prostu podążysz za pytaniami tutaj za pomocą znacznika "obietnica", wiele się nauczysz, ponieważ znajdziesz autorów i zwolenników głównych obiecujących bibliotek odpowiadających na pytania tutaj lub komentujących rzeczy. – jfriend00

+0

Dzięki, będę to czytać. – Kuan

3

Błędy burzą się w obietnicach, dopóki nie zostaną złapane.

Jeśli masz następujące (<= wskazuje zawiera):

Promise1 <= Promise2.catch(e) <= Promise3 <= throw 

Następnie Promise3 rzuty i odrzuca. Promise2 odrzuca, a następnie zostaje złapany. Promise1 rozwiązuje się pomyślnie, ponieważ nie otrzymuje odrzucenia.

Promise1 <= Promise2.catch(e) <= Promise3 <= throw 
^ resolves^rejects   ^rejects 

Pomyśl o tym jako o asynchronicznej próbie/połowie.

Promise1 = Promise.reject(err); // or throw 

Promise2 = Promise1.catch(err => { 
    // error caught 
}); 

Promise3 = Promise1.catch(err => { 
    throw err; 
    // error not caught but thrown back 
}); 

// Now Promise1 is rejected. Promise2 is resolved. Promise3 is rejected. 

Musisz również wiedzieć, że każde połączenie then/catch tworzy nową obietnicę. Proponuję przeczytać Promises/A+ spec i zachować go jako odniesienie.

+0

Dzięki, czy obietnica utworzona przez to/catch jest taka sama jak zwrócona przez someOtherAsyncThing() w moim przypadku? – Kuan

+0

Nie. Każde 'then/catch' tworzy nową obietnicę. A każde wywołanie 'then' jest uruchamiane na' nextTick', więc nie jest to nawet operacja synchronizacji. Przeczytaj specyfikację, jest bardzo przydatny :) – Louy

+0

Również w twoim przypadku obietnica 'someOtherAsyncThing' nie istnieje nawet po wywołaniu metody' catch'. Pamiętaj, że wywołanie 'then/catch' jest operacją synchronizacji, podczas gdy deklaracja klonowania jest asynchroniczna. – Louy

2

Można catch() na wewnętrznej Obiecujemy:

a().then(function() { 
    return b().catch(function() { 
    console.log('boo'); 
    }); 
}).catch(function(error) { 
    console.log('oh no', error); 
}); 

If a() odrzuca "oh no" będą rejestrowane. Jeśli b() odrzuci, "boo" zostanie zalogowany, ale nie "oh no".

+0

Dzięki, więc zasadniczo kontekst połowu zmieni się w moim przypadku, zgodnie z tym, co wewnątrz wtedy()? – Kuan

+0

Zobacz inne odpowiedzi na to, jak działają łańcuchy obietnic, wyjaśniają to całkiem dobrze. –