2015-02-17 10 views
7

nie koniecznie chcą błędów, ale mam:Czy mogę wcześnie przerwać łańcuch przy pomocy obietnic Bluebird?

getFromDb().then (tradeData) -> 
    if not tradeData 
    # DO NOT CONTINUE THE CHAIN 
    else 
    getLatestPrice tradeData 
.then (latestPrice) -> 
    ... 
.then -> 
    ... 
.then -> 
    ... 
.catch (err) -> 
    next err 

żaden sposób dla mnie, aby przerwać łańcuch, jeśli nie ma tradeData?

+0

Nie można bezpośrednio zwrócić nowej obietnicy (takiej, której nie udało się rozwiązać jako odpowiednie) z 'then' w bb? Jeśli "niepowodzenie w łańcuchu" nie działa, to ... to wcale nie jest łańcuch. – user2864740

+0

Będziesz chciał rzucić okiem na [Przerwij obietnicę obietnicy i wywołaj funkcję opartą na kroku w łańcuchu, w którym został złamany] (http://stackoverflow.com/q/20714460/1048572) i [Obsługa wielu połowów w obiecującej sieci] (http://stackoverflow.com/q/26076511/1048572) – Bergi

Odpowiedz

7
getFromDb().then (tradeData) -> 
    if tradeData 
    getLatestPrice tradeData -> 
     .then (latestPrice) -> 
     ... 
     .then -> 
     ... 
     .then -> 
     ... 
     .catch (err) -> 
     next err 
    else 
    getSomethingElse -> 
     send("no data") 

w 3,0, będziesz w stanie to zrobić:

p = getFromDb().then (tradeData) -> 
    if not tradeData 
    send("no data"); 
    p.break() 
    else 
    getLatestPrice tradeData 
.then (latestPrice) -> 
    ... 
.then -> 
    ... 
.then -> 
    ... 
.catch (err) -> 
    next err 
+1

Co jeśli chcę zaimplementować dodatkową logikę rozgałęziania? Na przykład, jeśli istnieje 'tradeData', wykonaj pewne kroki, jeśli nie, wykonaj inne kroki? – Shamoon

+1

@Shamoon użyj 'else'a – Esailija

+0

@Shamoon: Oczywiście, możesz również" rzucić "wyjątek" brak danych "i [użyć odrzucenia dla kontroli przepływu] (http://stackoverflow.com/a/24663315/1048572). Będzie to szczególnie "nie kontynuować łańcucha", jak poprosiłeś – Bergi

7

Chociaż przyjętym odpowiedź, ale chciałbym powiedzieć wszystkim Googlersami że „przerwa()” funkcja została zmieniona do "cancel()"

używać coś takiego:

p = getFromDb().then (tradeData) -> 
    if not tradeData 
    send("no data"); 
    p.cancel(); // Look Here!!!!!!!!!!!!!!!! 
    else 
    getLatestPrice tradeData 
.then (latestPrice) -> 
    ... 
.then -> 
    ... 
.then -> 
    ... 
.catch (err) -> 
    next err 

Przedtem upewnij się, aby dodać następujące linie w C onfig:

Promise.config({ 
    cancellation: true 
}); 
+0

działa dla mnie dzięki – anhnt

0

Im po prostu zastanawiasz się, dlaczego nie biorąc korzyści z faktu, że można throw cokolwiek chcesz, a nie tylko coś, co jest instanceof Error. Uważa się to za złą praktykę? Moim zdaniem to zależy, zależy to od tego, co próbujesz osiągnąć. Łańcuch obietnicy może zostać przerwany z różnych powodów, ale ogólnie rzecz biorąc, te dwa przypadałyby na dwie grupy. Potrzebne są Classic error occur i early break in chain. Logicznie drugiego nie można uznać za coś, co powinno być instance of Error.

const handleError = (err) => { 
    ... 
} 

const skip = (reason, ..., ...) => { 
    /** 
    * construct whatever you like 
    * just for example here return reason 
    */ 
    return reason 
} 

Promise.resolve() 
.then(() => { 
    if (iShouldEndChainEarlier) { 
    throw skip('I would like to end chain earlier') 
    } 

    return asyncOperation1() 
}) 
.then(results => { 
    ... 
    return asyncOperation2(results) 
}) 
.then(... => { 
    ... 
}) 
.catch(interrupt => { 
    if (interrupt instanceof Error) { 
    return handleError(interrupt) 
    } 

    /** 
    * Handle breaking promise chain earlier 
    * having interrupt reason in scope 
    */ 
}) 

Jeśli logicznie, na początku przerwy w łańcuchu może być traktowane jako błąd (który może być całkowicie sprawę), można stworzyć swój własny błąd i rozróżniać dwa w catch bloku. Po prostu mówiąc, że można myśleć o innym podejściu (ach), gdy radzimy sobie z jakimkolwiek zakłóceniem, które może wystąpić w obiecującym łańcuchu.

Możemy argumentować, że można to uznać za coś przeciwko first error pattern w węźle. Jeśli wystąpi błąd, najlepszą praktyką będzie wywoływanie oddzwaniania, takiego jak callback(err), gdzie err naprawdę powinno być instanceof Error w innym przypadku callback(null, data). Ale z drugiej strony, mając na uwadze, że .catch(fn) jest dla mnie po prostu cukrem dla then(undefined, onRejected), wydaje się być wystarczająco dobry do obsłużenia parametru onRejected w zależności od sytuacji, w której się znajdujesz.

Powiązane problemy