javascript - Node.js Promise 函数在返回前卡住执行

标签 javascript node.js express

node.js 应用程序需要使用 Promise 来确保在运行后续命令之前返回一个函数的结果。但是,下面的代码在 getUser(theToken) promise 函数应该返回其值的地方卡住。 为了使 getUser(theToken) promise 函数能够返回它在内部生成的有效值,需要对下面的代码进行哪些具体更改?

app.get('/auth/provider/callback', function(req, res) {
    var queryData = url.parse(req.url, true).query;
    //This is the end of Step C in the flow
    // code was in the GET request, ex: http://localhost:8080/login?code=w6zGJO&state=IuaO63
    console.log('Finished Step C of Authorization Code Flow.  Welcome back from authserver');
    console.log('queryData.code is: ' + queryData.code);
    //Now start Step D in the flow
    console.log('About to start Step D of Authorization Code Flow. ');
    var tokenUrl = oAuthConfig.tokenUrl + '?grant_type=' + oAuthConfig.grantType + '&code='+queryData.code+'&client_id=' + oAuthConfig.clientID + '&redirect_uri=' + oAuthConfig.callbackUrl;
    request.post(tokenUrl, function(err, response, body){
        if(err){console.log('ERROR with token request.')}
        // Step E is the response received as follows:
        var data = JSON.parse(body);
        console.log('JSON data response is: ' + data);
        getUser(data.access_token).then(function(message) {
            console.log('in callback, jwtJSON is: ');console.log(message);
            res.redirect(somewhere);
        });
    });
    console.log('The POST is finished.  Waiting for response.');
    console.log('Step D.  Token Request Sent To AuthServer.');
});

然后在同一文件中下面的 getUser(theToken) 函数是:

function getUser(theToken) {//returns JWT
  return new Promise(function(resolve, reject) {
    console.log('in getUser, theToken is: ');console.log(theToken);
    var jwtJSON = { "token" : "anonymous" };
    request({
        method: 'GET', url: authServer + '/uaa/user', json: true, 
        auth: { user: null, password: null, sendImmediately: true, bearer: theToken }
    }, function (error, response, body) {
        if(error){
          console.log('in getUser, ERROR with user request.');console.log(error);
          jwtJSON = { "token" : "error" };
          return jwtJSON;//
        }
        else {
            var uname = '';var jwtUser = 'empty';
            console.log('in getUser, response.statusCode is: ');console.log(response.statusCode);
            if(body['name'] && body['name'].length > 0 ){ 
                uname = body['name'];console.log('uname is: ');console.log(uname);
                client.exists(uname, function(err, reply) {//Check to see if a Redis key for the user already exists
                    if (reply === 1) {//a redis key DOES exist
                        console.log('\"'+uname+'\" exists');
                        client.expire(uname, 10);//set the key to expire in 10 seconds.  use this to manage session length
                        client.hgetall(uname, function(err, object) {
                            if(object && object["jwt"]) {
                                jwtJSON = { "token" : object["jwt"] };
                                console.log('in getUser, jwtJSON is: ');console.log(jwtJSON);
                                return jwtJSON;
                            } else { return jwtJSON; }
                        });
                    } else {//a redis key DOES NOT exist
                        console.log('\"'+uname+'\" doesn\'t exist');
                        jwtUser = generateJwt(uname, authoritiesLocal);
                        client.hmset(uname, {//store a hash/object
                            'jwt' : jwtUser
                         });
                        jwtJSON = { "token" : jwtUser };console.log('in getUser, jwtJSON is: ');console.log(jwtJSON);
                        client.expire(uname, 10);//set the key to expire in 10 seconds.  use this to manage session length
                        return jwtJSON;
                    }
                });//end of Redis conditional block
                console.log('jwtJSON is: ');console.log(jwtJSON);
            } else { return jwtJSON; }
        };
    });
  });
};

控制台打印输出为:

Finished Step C of Authorization Code Flow.  Welcome back from authserver
queryData.code is: 0oxzu6
About to start Step D of Authorization Code Flow. 
The POST is finished.  Waiting for response.
Step D.  Token Request Sent To AuthServer.
JSON data response is: [object Object]
in getUser, theToken is: 
eyJ_SomeLongToken_hbG
in getUser, response.statusCode is: 
200
uname is: 
user
jwtJSON is: 
{ token: 'anonymous' }
"user" doesn't exist
in getUser, jwtJSON is: 
{ token: 'eyJ_TheSameLongToken_hbG' }

然后程序执行暂停几秒钟,然后第二次运行该序列,第二次产生错误,因为第二次没有填充任何变量。

最佳答案

您需要使用resolvereject 参数而不是返回值。我已将您的返回语句替换为 resolvereject。然后你传入在 then

的回调函数中应该可用的数据
function getUser(theToken) { //returns JWT
    return new Promise(function(resolve, reject) {
        console.log('in getUser, theToken is: ');
        console.log(theToken);
        var jwtJSON = {
            "token": "anonymous"
        };
        request({
            method: 'GET',
            url: authServer + '/uaa/user',
            json: true,
            auth: {
                user: null,
                password: null,
                sendImmediately: true,
                bearer: theToken
            }
        }, function(error, response, body) {
            if (error) {
                console.log('in getUser, ERROR with user request.');
                console.log(error);
                jwtJSON = {
                    "token": "error"
                };

                /* REJECT INSTEAD OF RETURN */
                reject(jwtJSON);
            } else {
                var uname = '';
                var jwtUser = 'empty';
                console.log('in getUser, response.statusCode is: ');
                console.log(response.statusCode);
                if (body.name && body.name.length > 0) {
                    uname = body.name;
                    console.log('uname is: ');
                    console.log(uname);
                    client.exists(uname, function(err, reply) { //Check to see if a Redis key for the user already exists
                        if (reply === 1) { //a redis key DOES exist
                            console.log('\"' + uname + '\" exists');
                            client.expire(uname, 10); //set the key to expire in 10 seconds.  use this to manage session length
                            client.hgetall(uname, function(err, object) {
                                if (object && object.jwt) {
                                    jwtJSON = {
                                        "token": object.jwt
                                    };
                                    console.log('in getUser, jwtJSON is: ');
                                    console.log(jwtJSON);
                                    /* RESOLVE INSTEAD OF RETURN */
                                    resolve(jwtJSON);
                                } else {
                                    /* RESOLVE INSTEAD OF RETURN */
                                    resolve(jwtJSON);
                                }
                            });
                        } else { //a redis key DOES NOT exist
                            console.log('\"' + uname + '\" doesn\'t exist');
                            jwtUser = generateJwt(uname, authoritiesLocal);
                            client.hmset(uname, { //store a hash/object
                                'jwt': jwtUser
                            });
                            jwtJSON = {
                                "token": jwtUser
                            };
                            console.log('in getUser, jwtJSON is: ');
                            console.log(jwtJSON);
                            client.expire(uname, 10); //set the key to expire in 10 seconds.  use this to manage session length

                            /* RESOLVE INSTEAD OF RETURN */
                            resolve(jwtJSON);
                        }
                    }); //end of Redis conditional block
                    console.log('jwtJSON is: ');
                    console.log(jwtJSON);
                } else {
                    /* RESOLVE INSTEAD OF RETURN */
                    resolve(jwtJSON);
                }
            }
        });
    });
}

关于javascript - Node.js Promise 函数在返回前卡住执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38490693/

相关文章:

javascript - 我的 Node.js 收到 Route.post() got a object Undefined 错误

javascript - NodeJS 示例应用无法启动,无法找到 'config'?

javascript - 使用 Vue.JS 动态添加行到表单

javascript - typescript 模块没有导出成员 - react

javascript - 带有 Angular 2 rc.5 的 NodeJs 路由目录

ruby-on-rails - 打包 html 模板、javascript 和 css 以供多个平台使用

javascript - Socket.io 从一个事件发出多条消息

node.js - web3.eth.getBlockNumber 返回 { [函数 : get] request: [Function: bound]}

javascript - 如果不匹配用户名则禁用按钮

javascript - Breezejs angularjs 中的双重麻烦