关于node.js:那么如何在promise中处理if-else?

How to handle the if-else in promise then?

在某些情况下,当我从promise对象获取返回值时,我需要根据值的条件来启动两个不同的then()进项,例如:

1
2
3
4
5
6
7
promise().then(function(value){
    if(//true) {
        // do something
    } else {
        // do something
    }
})

我在想也许我可以这样写:

1
2
3
4
5
6
7
8
promise().then(function(value){
    if(//true) {
        // call a new function which will return a new promise object
        ifTruePromise().then();
    } else {
        ifFalsePromise().then();
    }
})

但与此同时,我有两个问题:

  • 我不确定开始一个新的承诺是否是个好主意,然后在承诺中进行流程;

  • 如果我需要两个进程在最后一个函数中调用怎么办? 这意味着它们具有相同的"终端"

  • 我试图返回新的承诺,以保持原始链像:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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);

    但是在这种情况下,无论是true还是false,下一个then都会起作用。

    那么,处理它的最佳实践是什么?


    只要您的函数返回承诺,就可以使用建议的第一种方法。

    下面的小提琴显示了如何根据第一个解析的值采用不同的链接路径。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    function myPromiseFunction() {
    \t//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) {

    });

    您也可以只进行一个条件链接,将返回承诺分配给变量,然后继续执行应以任何一种方式运行的功能。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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
    });

    我写了一个简单的包,用于有条件的Promise。

    如果您想检查一下:

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

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

    在询问有关软件包如何解决问题的评论时:

    1,它有两个对象。

    2,此包中的Branch对象是要在then()或catch()中使用的功能(例如onFulfilled和onRejected)的临时存储位置。它具有诸如then()和catch()之类的方法,它们采用与Promise中的相??应方法相同的参数。当您在Branch.then()或Branch.catch()中传递回调时,请使用与Promise.then()和Promise.catch()相同的语法。然后什么也不要做,只能将回调存储在数组中。

    3,Condition是一个JSON对象,用于存储条件和其他信息以进行检查和分支。

    4,您可以在promise回调中使用条件对象来指定条件(布尔表达式)。然后,Condition存储您传递的信息。在用户提供了所有必要的信息之后,condition对象使用一种方法来构造全新的Promise对象,该对象采用以前存储在Branch对象中的承诺链和回调信息。这里有些棘手的部分是您(作为实现者,而不是用户)必须解决/拒绝在链接存储的回调之前首先手动构建的Promise。这是因为否则,新的承诺链将不会启动。

    5,由于事件循环,可以在拥有茎Promise对象之前或之后实例化Branch对象,并且它们不会互相干扰。我在这里使用术语"分支"和"词干",因为该结构类似于一棵树。

    示例代码可以在npm和github页面上找到。

    顺便说一句,此实现还使您可以在分支内拥有分支。而且分支机构不必位于检查条件的同一位置。


    这就是我在fetch()中所做的方式,我不确定这是否正确,但是可以

    1
    2
    3
    4
    5
    6
    7
    8
     fetch().then(res => res.ok ? res : false).then(res => {
        if (res) {
            //res ok
        } else {
           //res not ok
        }

    });