有没有办法在延迟Promise中提前返回?

IT技术 javascript promise q
2021-03-16 14:42:20

所以我有一个Promise,其中包含多个这样的检查

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 之前返回,但我想知道是否有类似返回的东西?

2个回答

尽量不要创建单个延迟,它可能会被函数的多个部分拒绝,并且您需要在每个退出点返回。
取而代之的是,使用单独的 Promise 进行编码,每个控制流分支对应一个。您可以使用Q.rejectQ.Promise构造函数- 避免弃用的延迟模式。您的函数将如下所示:

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,这样return Q.reject(…);您就可以不用编写,而只需执行throw …;.

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然后拒绝它,你不能这样做,return deferred.reject()因为它不返回一个promise,它会抛出错误。这样做可以避免金字塔。
2021-04-24 14:42:20
但是您可以简单地deferred.reject(); return deferred.promise;(如果您不想使用我的答案中更简单的版本)。不需要异步回调。
2021-05-14 14:42:20