Is there a way to return early in deferred promise?

谁说胖子不能爱 提交于 2019-12-17 06:54:21

问题


So I have a promise which contains multiple checks like this

function test(){
    var deferred = q.defer()
    var passed = false
    if(!passed){
        deferred.reject("Don't proceed")
        //return
    } else {
        if(!passed){
            deferred.reject("Don't proceed")
        } else {
            if(!passed){
                deferred.reject("Don't proceed")
            } else {
                setTimeout(function(){
                    console.log("Hello");
                    deferred.resolve()
                }, 100);
            }
        }
    }
    return deferred.promise
}

This looks bad because there is a pyramid at the bottom. I'm wondering is there something like return in 'q' which can make the code look better? For example like this:

function test(){
    var deferred = q.defer()
    var passed = false
    if(!passed){
        deferred.reject("Don't proceed")
        return
    }
    if(!passed){
        deferred.reject("Don't proceed")
        return
    }
    if(!passed){
        deferred.reject("Don't proceed")
        return
    } 
    setTimeout(function(){
        console.log("Hello");
        deferred.resolve()
    }, 100);
    return deferred.promise
}

This definitely doesn't work because it returned before promise is returned, but I'm wondering is there something like a return?


回答1:


Try not to create a single deferred, that could be rejected from multiple parts of your function, and which you would need to return at every exit point.
Instead, code with separate promises, one for each branch of control flow you have. You can use Q.reject and the Q.Promise constructor - avoid the deprecated deferred pattern. Your function would then look like this:

function test() {
    var deferred = q.defer()
    var passed = false
    if (!passed)
        return Q.reject("Don't proceed");
    if (!passed)
        return Q.reject("Don't proceed");
    if (!passed)
        return Q.reject("Don't proceed");
    // else
    return new Promise(function(resolve) {
        setTimeout(function(){
            console.log("Hello");
            resolve();
        }, 100);
    });
}

Alternatively, you can wrap your test function in Q.fbind, so that instead of writing return Q.reject(…); you could just do throw …;.




回答2:


function test(){
    var deferred = q.defer()
    var passed = false
    if(true){
        deferred.reject(new Error("Don't proceed1"))
        return deferred.promise
    }
    if(!passed){
        deferred.reject(new Error("Don't proceed2"))
        return deferred.promise
    }
    if(!passed){
        deferred.reject(new Error("Don't proceed3"))
        return deferred.promise
    } 
    setTimeout(function(){
        console.log("Hello");
        deferred.resolve()
    });
    return deferred.promise
}

I think this is the best way, thank to Bergi



来源:https://stackoverflow.com/questions/31933675/is-there-a-way-to-return-early-in-deferred-promise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!