那么如何处理if-else中的诺言?


86

在某些情况下,当我从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. 如果我需要两个进程在最后一个函数中调用怎么办?这意味着它们具有相同的“终端”

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

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都可以。

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


Answers:


60

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

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

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

4

我写了一个简单的包,用于有条件的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页面上找到。

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


看来您是在提供评论而不是答案。拥有足够的声誉后,您就可以在任何帖子中发表评论。还要检查一下该怎么办
thewaywere是

@thewaywewere,我已添加响应您的请求的实施详细信息。
szl1919

0

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

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

});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.