多个函数返回promise

问题描述 投票:0回答:1

我有一个HTTP助手,它为每个请求返回一个promise。有时这些请求相互依赖。我很困惑自己编写我认为反模式的代码。

通常在链接承诺时使用.then()

function giveMeASimplePromise(){
     return new Promise( function(resolve, reject){
          setTimeout( function(){
               console.log("I'm finishing a promise.");
               resolve();
          }, 3000 );
     });
}

giveMeASimplePromise().then( giveMeASimplePromise ).then( giveMeASimplePromise );

//prints 'I'm finishing a promise' 3 times spaced 3 seconds apart

但是,如果其中一个承诺中有一个需要成为链条一部分的承诺,我会感到困惑。

这对我来说是因为我有一个HTTP帮助函数,它返回每个请求的promise。其中一些请求相互依赖。整个过程需要返回一个保持一切异步的承诺。

function login( credentials ){
    //outer promise that's returned and either needs to resolve or reject based
    // on complete login cycle
    return new Promise( function(resolve, reject){
        //inner promise checking for username/password match. can be rejected 
        // for several reasons.
        var checkCredentials = httpHelper.checkCredentials( credentials );
        checkCredentials.then( function(result){
            if ( result.credentialsMatch ){
                //another inner promise checking for privilege levels. never rejects.
                var checkPrivileges = httpHelper.getPrivileges( result.userID ); 
                getPrivileges.then( function(result) ){
                    if( result.privilege > 0 ){
                        //want this to resolve the entire chain
                        resolve();
                    }else{
                        //want this to reject the entire chain
                        reject('You do not have sufficient privileges.');
                    }
                }
            }else{
                reject('Incorrect username and/or password.');
            }
        }).catch( function(reason){
            reject( reason );
        });
    });
}

var credentials = { ... };
var loginResult = login( credentials ).then( function(value){
    console.log('Logged in successfully.');
}).catch( function(reason){
    console.log('Could not log in: ', reason);
})

这是一种反模式,对吧?感觉不对。

javascript promise
1个回答
2
投票

当您已经从您使用的服务获得承诺时,您确实不需要使用new创建承诺。在这种情况下,只需在其上使用该承诺和链,最后返回链式承诺。

当不使用new Promise时,你显然不会打电话给reject。而是在throw回调中的then。嵌套的then调用也应该更好地向上移动一级,这样你就可以得到一个扁平的then链。

这是如何看起来:

function login(credentials) {
    return httpHelper.checkCredentials(credentials).then(function(result) {
        if (!result.credentialsMatch) throw "Wrong credentials!";
        return httpHelper.getPrivileges(result.userID); // Don't chain here, but return!
    }).then(function(result) {
        if (result.privilege <= 0) throw "You do not have sufficient privileges.";
    });
}

您可能知道,当您使用async/await语法时,事情看起来更简单:

async function login(credentials) {
    const result = await httpHelper.checkCredentials(credentials);
    if (!result.credentialsMatch) throw "Wrong credentials!";
    const result2 = await httpHelper.getPrivileges(result.userID);
    if (result2.privilege <= 0) throw "You do not have sufficient privileges.";
}
© www.soinside.com 2019 - 2024. All rights reserved.