2016-07-20 33 views
1

node.js应用程序需要使用Promise来确保在运行后续命令之前返回一个函数的结果。但是,下面的代码冻结在getUser(theToken)的内部,promise函数应该返回它的值。 为了使getUser(theToken) promise函数能够返回它在内部生成的有效值,需要对下面的代码进行哪些特定的更改?Node.js 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' } 

然后程序执行的序列之前停止几秒钟第二次运行,第二次产生错误,因为没有变量保持第二次填充。

+0

回调函数你真的应该花约1小时阅读如何组织的承诺,它们是如何工作的数据。这将为您节省数周的头痛。这里有一个很好的开始,让你的代码不老鸡蛋的气味:http://solutionoptimist.com/2013/12/27/javascript-promise-chains-2/ –

+0

@JasonSebring谢谢。我会仔细阅读你的链接。在创建这篇文章之前,我也花了几个小时阅读类似的链接。阅读至关重要。但是我们很多人都需要对代码示例进行交互式讨论,才能真正了解API的工作原理。 – FirstOfMany

回答

3

您需要使用参数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); 
       } 
      } 
     }); 
    }); 
} 
+0

感谢您和+1,让我们用简单易懂的答案来教育我们。这为我持续的阅读增加了很多洞察力。 – FirstOfMany

相关问题