web-dev-qa-db-fra.com

Comment gérer le if-else promis alors?

Dans certains cas, lorsque j'obtiens une valeur de retour d'un objet de promesse, je dois démarrer deux précessions then() différentes qui dépendent de la condition de la valeur, comme suit:

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

Je pense que je peux peut-être l'écrire comme ceci:

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

mais avec cela, j'ai deux questions:

  1. Je ne suis pas sûr que ce soit une bonne idée de commencer une nouvelle promesse, puis de la transformer en une promesse;

  2. que faire si j'ai besoin du processus deux pour appeler une fonction dans la dernière? Cela signifie qu'ils ont le même "terminal"

J'ai essayé de retourner la nouvelle promesse de garder la chaîne originale comme:

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

mais dans ce cas, que ce soit vrai ou faux, la prochaine then fonctionnera.

SO, quelle est la meilleure pratique pour le gérer?

59
Brick Yang

Tant que vos fonctions renvoient une promesse, vous pouvez utiliser la première méthode que vous proposez.

Le violon ci-dessous montre comment vous pouvez utiliser différents chemins de chaînage en fonction de la valeur résolue en premier.

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) {

});

Vous pouvez également créer un chaînage conditionnel, affecter la promesse de retour à une variable, puis continuer à exécuter les fonctions à exécuter dans les deux sens.

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
});
42
Daniel B

J'ai écrit un paquet simple pour une utilisation de promesse conditionnelle. 

Si vous voulez le vérifier:

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

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

En réponse à des commentaires demandant comment le paquet résout le problème:

1, il a deux objets.

2, l’objet Branch de ce package est un emplacement de stockage temporaire pour les fonctions telles que onFulfilled et onRejected que vous souhaitez utiliser dans then () ou catch (). Il a des méthodes telles que then () et catch () qui prennent les mêmes arguments que leurs homologues dans Promise. Lorsque vous transmettez un rappel dans Branch.then () ou Branch.catch (), utilisez la même syntaxe que Promise.then () et Promise.catch (). Ensuite, ne rien faire d'autre que stocker les rappels dans un tableau.

3, Condition est un objet JSON qui stocke les conditions et d’autres informations pour la vérification et la création de branches.

4, vous spécifiez des conditions (expression booléenne) à l'aide d'un objet de condition dans les rappels de promesse. La condition stocke ensuite les informations que vous transmettez. Une fois que l'utilisateur a fourni toutes les informations nécessaires, l'objet condition utilise une méthode pour construire un nouvel objet Promise qui prend en charge la chaîne de promesse et les informations de rappel précédemment stockées dans l'objet Branch. Une partie délicate ici est que vous (en tant qu’implémenteur, et non utilisateur) devez résoudre/rejeter la promesse que vous avez créée manuellement avant de chaîner les rappels stockés. En effet, sinon, la nouvelle chaîne de promesses ne démarrera pas. 

5, Grâce à la boucle d’événements, les objets Branch peuvent être instanciés avant ou après la création d’un objet stem Promise et ils n’interféreront pas les uns avec les autres. J'utilise les termes "branche" et "tige" ici parce que la structure ressemble à un arbre. 

Vous trouverez un exemple de code sur les pages npm et github. 

A propos, cette implémentation vous permet également d'avoir des branches au sein d'une branche. Et les branches ne doivent pas nécessairement être au même endroit que vous vérifiez les conditions. 

3
szl1919

Voici comment je l’ai fait dans ma fonction fetch (). Je ne sais pas si c’est la bonne façon, mais cela fonctionne.

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

});
0
Servus