W niektórych przypadkach, gdy otrzymam wartość zwracaną z obiektu obietnicy, muszę rozpocząć dwie różne then()
procedury zależne od stanu wartości, na przykład:
promise().then(function(value){
if(//true) {
// do something
} else {
// do something
}
})
Myślę, że może mógłbym to napisać tak:
promise().then(function(value){
if(//true) {
// call a new function which will return a new promise object
ifTruePromise().then();
} else {
ifFalsePromise().then();
}
})
ale w związku z tym mam dwa pytania:
Nie jestem pewien, czy to dobry pomysł, aby rozpocząć nową obietnicę, a następnie przetworzyć obietnicę;
co, jeśli potrzebuję dwóch procesów, aby wywołać jedną funkcję w ostatniej? Oznacza to, że mają ten sam „terminal”
Próbowałem zwrócić nową obietnicę zachowania oryginalnego łańcucha, jak:
promise().then(function(value){
if(//true) {
// call a new function which will return a new promise object
// and return it
return ifTruePromise();
} else {
// do something, no new promise
// hope to stop the then chain
}
}).then(// I can handle the result of ifTruePromise here now);
ale w tym przypadku, czy to prawda, czy fałsz, następny then
zadziała.
Więc jaka jest najlepsza praktyka, aby sobie z tym poradzić?
node.js
asynchronous
promise
Brick Yang
źródło
źródło
Odpowiedzi:
Tak długo, jak Twoje funkcje zwracają obietnicę, możesz użyć pierwszej sugerowanej metody.
Poniższe skrzypce pokazują, jak możesz wybrać różne ścieżki łańcuchowe w zależności od tego, jaka będzie pierwsza rozstrzygnięta wartość.
function myPromiseFunction() { //Change the resolved value to take a different path return Promise.resolve(true); } function conditionalChaining(value) { if (value) { //do something return doSomething().then(doSomethingMore).then(doEvenSomethingMore); } else { //do something else return doSomeOtherThing().then(doSomethingMore).then(doEvenSomethingMore); } } function doSomething() { console.log("Inside doSomething function"); return Promise.resolve("This message comes from doSomeThing function"); } function doSomeOtherThing() { console.log("Inside doSomeOtherthing function"); return Promise.resolve("This message comes from doSomeOtherThing function"); } function doSomethingMore(message) { console.log(message); return Promise.resolve("Leaving doSomethingMore"); } function doEvenSomethingMore(message) { console.log("Inside doEvenSomethingMore function"); return Promise.resolve(); } myPromiseFunction().then(conditionalChaining).then(function () { console.log("All done!"); }). catch (function (e) { });
Możesz także po prostu utworzyć jeden łańcuch warunkowy, przypisać obietnicę zwrotu do zmiennej, a następnie kontynuować wykonywanie funkcji, które powinny być uruchamiane w obie strony.
function conditionalChaining(value){ if (value) { //do something return doSomething(); } else{ //do something else return doSomeOtherThing(); } } var promise = myPromiseFunction().then(conditionalChaining); promise.then(function(value){ //keep executing functions that should be called either way });
źródło
Napisałem prosty pakiet do warunkowego stosowania przyrzeczenia.
Jeśli chcesz to sprawdzić:
Strona npm: https://www.npmjs.com/package/promise-tree
i github: https://github.com/shizongli94/promise-tree
W odpowiedzi na uwagi z pytaniem, jak pakiet rozwiązuje problem:
1, ma dwa obiekty.
2, obiekt Branch w tym pakiecie jest tymczasowym miejscem przechowywania funkcji, takich jak onFulfilled i onRejected, których chcesz użyć w then () lub catch (). Posiada metody, takie jak then () i catch (), które pobierają te same argumenty, co ich odpowiedniki w Promise. Kiedy przekazujesz wywołanie zwrotne w Branch.then () lub Branch.catch (), użyj tej samej składni, co Promise.then () i Promise.catch (). Następnie nie rób nic poza przechowywaniem wywołań zwrotnych w tablicy.
3, Stan to obiekt JSON, który przechowuje warunki i inne informacje do sprawdzania i rozgałęziania.
4. Określasz warunki (wyrażenie boolowskie) za pomocą obiektu warunku w wywołaniach zwrotnych obietnicy. Warunek następnie przechowuje informacje, które przekazujesz. Po dostarczeniu wszystkich niezbędnych informacji przez użytkownika, obiekt warunku używa metody do skonstruowania zupełnie nowego obiektu Promise, który przyjmuje informacje z łańcucha obietnic i wywołań zwrotnych, które zostały wcześniej zapisane w obiekcie Branch. Trochę trudna część polega na tym, że Ty (jako osoba wdrażająca, a nie użytkownik) musisz rozwiązać / odrzucić obietnicę, którą najpierw zbudowałeś ręcznie, zanim połączysz zapisane wywołania zwrotne. Dzieje się tak, ponieważ w przeciwnym razie nowy łańcuch obietnic nie rozpocznie się.
5, Dzięki pętli zdarzeń obiekty Branch mogą być tworzone przed lub po utworzeniu macierzystego obiektu Promise i nie będą ze sobą kolidować. Używam tutaj terminów „gałąź” i „łodyga”, ponieważ struktura przypomina drzewo.
Przykładowy kod można znaleźć na stronach npm i github.
Nawiasem mówiąc, ta implementacja umożliwia również posiadanie oddziałów w oddziale. A oddziały nie muszą znajdować się w tym samym miejscu, w którym sprawdzasz warunki.
źródło
Tak to zrobiłem w moim fetch () Nie jestem pewien, czy to jest właściwy sposób, ale działa
fetch().then(res => res.ok ? res : false).then(res => { if (res) { //res ok } else { //res not ok } });
źródło