【问题标题】:Is there a way to return early in deferred promise?有没有办法在延期承诺中提前返回?
【发布时间】:2015-08-11 05:10:14
【问题描述】:

所以我有一个包含多个这样的检查的承诺

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
}

这看起来很糟糕,因为底部有一个金字塔。我想知道“q”中是否有类似 return 的东西可以使代码看起来更好?比如这样:

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
}

这绝对行不通,因为它在返回 promise 之前返回,但我想知道是否有类似 return 的东西?

【问题讨论】:

  • 为什么不使用if (passed)继续,然后在函数的最后,你可以做一个测试,看看你是否应该拒绝。
  • 在每种情况下,您都可以返回 deferred.promise 而不是只返回。不过会很乱。

标签: javascript promise q


【解决方案1】:

尽量不要创建单个 deferred,它可能会被您的函数的多个部分拒绝,并且您需要在每个退出点返回它。
取而代之的是,带有单独承诺的代码,一个用于您拥有的控制流的每个分支。您可以使用Q.reject 和Q.Promise constructor - 避免不推荐使用的延迟模式。您的函数将如下所示:

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

或者,您可以将test 函数包装在Q.fbind 中,这样您就可以使用throw …; 而不是编写return Q.reject(…);。

【讨论】:

    【解决方案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
    }
    

    我认为这是最好的方法,感谢 Bergi

    【讨论】:

    • 该函数需要先返回一个promise,所以它先返回一个promise然后reject它,你不能这样做return deferred.reject(),因为它不返回一个promise,它会抛出错误。这样做可以避免金字塔。
    • 但是您可以简单地deferred.reject(); return deferred.promise; (如果您不想使用我回答中更简单的版本)。不需要异步回调。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多