我试图制作一系列Promises函数,这些函数在NodeJS和Kraken框架中使用HTTP请求。
我的代码可以在90%的情况下工作,但如果远程请求的服务器需要时间来响应,代码将返回带有未定义值的错误。所以我认为Q是防止这种情况的好方法。
以下是这种情况:
我们使用"代码"访问网址参数 - >路由控制器使用此参数在HTTP POST请求中使用它 - >响应(令牌)存储在变量中并用于其他HTTP GET请求 - >响应(多个JSON对象)也存储在变量中 - >所有变量都存储在MongoDB中。 如果函数没有按此顺序使用,当然会失败。
var Q = require('q');
module.exports = function (router) {
router.get('/', function (req, res) {
var codein = req.param('code');
if(codein){
console.log('Provided code: ' + codein+'\n');
getAccessToken(codein).then(function(token){
console.log('Provided AccessToken: ' + token + '\n');
getUsername(token).then(function(userdata){
console.log('Provided Username: ' + JSON.parse(userdata).username + '\n');
storeData(userdata).then(function(msg){
console.log(msg);
res.redirect('/dashboard/' + JSON.parse(userdata).username);
});
});
});
}
else{
console.log('Access Denied, redirecting...');
res.redirect('/');
}
});
};
此方法有效,但实际上并没有解决问题,因为有时变量未定义。我认为我的请求功能并不是很好......
这是POST请求的第一个函数示例:
var getAccessToken = function(cod){
var def = Q.defer();
var data = querystring.stringify({
client_id:"1234567890",
client_secret:"******",
grant_type:"authorization_code",
redirect_uri:"http://localhost:8000/r/callback",
code:cod
});
var options = {
host: 'domain.server.com',
port: 443,
path: '/api/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(data)
}
};
var response = "";
var req = https.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
response += chunk;
});
res.on('end', function(){
var json = JSON.parse(response);
var acto = json.access_token;
def.resolve(acto);
});
});
req.write(data);
req.end();
return def.promise;
};
在这种情况下,acto变量可能是未定义的...所以我以错误的方式使用Q?
修改
要理解我的问题,让我告诉你我的输出控制台中我能拥有什么(真的很少见但是发生):
Provided code: 12345678910
Provided Username: user543210
而不是:
Provided code: 12345678910
Provided AccessToken: 9876543210
Provided Username: user
答案 0 :(得分:2)
我认为你需要考虑2个场景
代码
res.on('end', function(){
var json = JSON.parse(response);
var acto = json.access_token;
def.resolve(acto);
});
应修改为:
try {
var json = JSON.parse(response);
var acto = json.access_token;
//check if acto is undefined
if (acto === undefined) {
def.reject('Some error message');
} else {
def.resolve(acto);
}
} catch (error) {
//since the JSON could not be parse
def.reject(error);
}