那么如何处理if-else的承诺呢?

时间:2015-10-21 10:52:18

标签: node.js asynchronous promise

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

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

我想也许我可以这样写:

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. 我试图返回新的承诺,以保持原始链:

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

    但在这种情况下,无论是真还是假,下一个then都可以。

    那么,处理它的最佳做法是什么?

3 个答案:

答案 0 :(得分:46)

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

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

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

});

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

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

答案 1 :(得分:3)

我已经为条件承诺使用编写了一个简单的包。

如果你想看看它:

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回调中的条件对象指定条件(布尔表达式)。条件然后存储您传入的信息。在用户提供所有必要信息之后,条件对象使用一种方法构造全新的Promise对象,该对象获取先前存储在Branch对象中的promise链和回调信息。这里有一点棘手的部分是你(作为实现者,而不是用户)必须在链接存储的回调之前解析/拒绝你首先手动构造的Promise。这是因为否则,新的承诺链不会开始。

5,由于事件循环,Branch对象可以在你拥有一个干Promise对象之前或之后被实例化,并且它们不会相互干扰。我使用条款" branch"和"干"这里因为结构类似于树。

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

顺便说一句,此实现还允许您在分支中拥有分支。并且分支机构不必在您检查条件的同一个地方。

答案 2 :(得分:0)

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

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

});