Jak poradzić sobie z obietnicą if-else?

W niektórych przypadkach, gdy otrzymuję wartość zwracaną z obiektu promise, muszę uruchomić dwa różne precesy then() zależne od warunku wartości, takie jak:

promise().then(function(value){
    if(//true) {
        // do something
    } else {
        // do something 
    }
})

Myślę, że może napiszę to tak:

promise().then(function(value){
    if(//true) {
        // call a new function which will return a new promise object
        ifTruePromise().then();
    } else {
        ifFalsePromise().then();
    }
})

Ale z tym mam dwa pytania:

  1. Nie jestem pewien, czy to dobry pomysł, aby rozpocząć nową obietnicę-następnie proces w obietnicy;

  2. Co jeśli potrzebuję dwóch procesów, aby wywołać jedną funkcję w ostatnim? To znaczy, że mają ten sam "terminal"

Starałem się zwrócić nową obietnicę, aby zachować oryginalny łańcuch 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ć?

Author: Brick Yang, 2015-10-21

3 answers

Dopóki twoje funkcje zwracają obietnicę, możesz użyć pierwszej metody, którą sugerujesz.

Poniższy fiddle pokazuje, jak można przyjmować różne ścieżki łańcucha w zależności od tego, jaka będzie pierwsza rozwiązana 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 również wykonać jeden łańcuch warunkowy, przypisać obietnicę powrotu do zmiennej, a następnie kontynuować wykonywanie funkcji, które powinny być uruchomione 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
});
 61
Author: Daniel B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-21 13:30:25

Napisałem prosty pakiet do warunkowego użycia obietnicy.

Jeśli chcesz to sprawdzić:

Npm page: https://www.npmjs.com/package/promise-tree

I github: https://github.com/shizongli94/promise-tree

W odpowiedzi na komentarze pytające jak pakiet rozwiązuje problem:

1, posiada dwa obiekty.

2, Obiekt Branch w tym pakiecie jest tymczasowym miejscem przechowywania funkcji takich jak onFulfilled i onRejected that you want to use in then () or catch (). Posiada metody takie jak then() I catch (), które przyjmują te same argumenty co odpowiedniki w Promise. Kiedy zdasz w callback w Branch.then () lub Branch.catch(), używa tej samej składni co Promise.wtedy () i obietnica.catch (). Następnie nie rób nic poza przechowywaniem wywołań zwrotnych w tablicy.

3, Condition jest obiektem JSON, który przechowuje warunki i inne informacje do sprawdzania i rozgałęziania.

4, określasz warunki (wyrażenie logiczne) użycie obiektu condition w wywołaniach zwrotnych promise. Condition następnie przechowuje informacje, które przekazujesz. Po dostarczeniu wszystkich niezbędnych informacji przez użytkownika, obiekt condition wykorzystuje metodę do zbudowania zupełnie nowego obiektu Promise, który pobiera informacje o łańcuchu obietnic i wywołaniu zwrotnym wcześniej przechowywanym w obiekcie Branch. Nieco trudniejsze jest to, że Ty (jako wykonawca, a nie użytkownik) musisz rozwiązać / odrzucić obietnicę, którą najpierw skonstruowałeś ręcznie przed połączeniem przechowywanych rozmowy 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 obiektu Stem Promise i nie będą się ze sobą kolidować. Używam tu 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 gałęzi w gałęzi. I gałęzie do nie musisz być w tym samym miejscu, w którym sprawdzasz warunki.

 4
Author: szl1919,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-26 01:50:21

Tak to zrobiłem w moim aportowaniu () nie jestem pewien, czy to jest właściwa droga, ale to działa

 fetch().then(res => res.ok ? res : false).then(res => {
    if (res) {
        //res ok
    } else {
       //res not ok
    }

});
 0
Author: Servus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-04 08:43:45