nodejs 同步问题与 q
nodejs sync issue with q
我用http get 获取了一个json,但是不能把它传递到首页,即使我已经使用了q,有用的是可以执行同步,但仍然有问题,有人可以帮忙吗?
//getturnto.js
var conf = require("../conf/setting.json");
var http = require("http");
function TurnToUGC(){
if(!(this instanceof TurnToUGC)){
return new TurnToUGC();
}
};
TurnToUGC.prototype.getUGCJson = function(item,callback){
var UGCPath = conf.UGCPath;
var options = {
host:conf.UGCHost,
port:conf.UGCPort,
path:UGCPath
};
http.get(options,function(res){
var buf = "";
res.on("data",function(d){
buf += d;
});
res.on("error",function(error){
callback(error);
});
res.on("end", function () {
var ret;
try{
ret = JSON.parse(buf);
}catch (err){
return callback(err);
}
callback(null,ret);
})
}).on("error",function(er){
console.log(er);
});
};
module.exports = TurnToUGC;
然后我想展示它,(我用express生成了一个简单的网页)
//这是router.index
var q = require("q");
exports.index = function(req, res,next){
var getturnto = require("getturnto")();
q().then(function(){
getturnto.getUGCJson(null,function(err,re){
if(err){
console.log(err);
return {"error":err};
}else {
console.log(re);
return re;
}
});
})
.then(function(UGCData){
res.render('index',
{ title: 'Get UGC Content',
data:UGCData
}
);
})
.fail(function(err){
console.log(err);
next(err);
});
}
json可以在控制台打印出来,但是"UGCData"总是undefined,json对象不能传递到首页。
请阅读承诺的传播here。由于您的 getturnto.getUGCJson
是异步的,因此您的第一个输出处理程序是 returning undefined
。这就是您在 UGCData
中变得不确定的原因。您需要做的是 return 第一个输出处理程序中的承诺。试试这个方法:
var q = require("q");
exports.index = function(req, res,next){
var getturnto = require("getturnto")();
q().then(function(){
var deferred = q.defer();
getturnto.getUGCJson(null,function(err,re){
if(err){
console.log(err);
deferred.reject(new Error(error));
}else {
console.log(re);
deferred.resolve(re);
}
});
return deferred.promise;
})
.then(function(UGCData){
res.render('index',
{ title: 'Get UGC Content',
data:UGCData
}
);
})
.fail(function(err){
console.log(err);
next(err);
});
}
如果您将 getUGCJson
重写为 return 承诺会更好。
最终版本:
1.getturnto.js
.....
TurnToUGC.prototype.getUGCJson = function(){
*var deferred = q.defer();*
http.get(options,function(res){
....
res.on("error",function(error){
*deferred.reject(new Error(error))*;
});
res.on("end", function () {
try{
*deferred.resolve(JSON.parse(buf));*
}catch (err){
console.log(err);
}
})
}).on("error",function(er){
console.log(er);
});
*return deferred.promise;*
};
module.exports = TurnToUGC;
2.router
getturnto.getUGCJson(null).then(function(UGCData){
res.render('index',
{ title: 'Get UGC Content',
data:UGCData,
comments:UGCData.comments,
questions:UGCData.questions
}
);
})
.fail(function(err){
console.log(err);
next(err);
});
}
我用http get 获取了一个json,但是不能把它传递到首页,即使我已经使用了q,有用的是可以执行同步,但仍然有问题,有人可以帮忙吗? //getturnto.js
var conf = require("../conf/setting.json");
var http = require("http");
function TurnToUGC(){
if(!(this instanceof TurnToUGC)){
return new TurnToUGC();
}
};
TurnToUGC.prototype.getUGCJson = function(item,callback){
var UGCPath = conf.UGCPath;
var options = {
host:conf.UGCHost,
port:conf.UGCPort,
path:UGCPath
};
http.get(options,function(res){
var buf = "";
res.on("data",function(d){
buf += d;
});
res.on("error",function(error){
callback(error);
});
res.on("end", function () {
var ret;
try{
ret = JSON.parse(buf);
}catch (err){
return callback(err);
}
callback(null,ret);
})
}).on("error",function(er){
console.log(er);
});
};
module.exports = TurnToUGC;
然后我想展示它,(我用express生成了一个简单的网页) //这是router.index
var q = require("q");
exports.index = function(req, res,next){
var getturnto = require("getturnto")();
q().then(function(){
getturnto.getUGCJson(null,function(err,re){
if(err){
console.log(err);
return {"error":err};
}else {
console.log(re);
return re;
}
});
})
.then(function(UGCData){
res.render('index',
{ title: 'Get UGC Content',
data:UGCData
}
);
})
.fail(function(err){
console.log(err);
next(err);
});
}
json可以在控制台打印出来,但是"UGCData"总是undefined,json对象不能传递到首页。
请阅读承诺的传播here。由于您的 getturnto.getUGCJson
是异步的,因此您的第一个输出处理程序是 returning undefined
。这就是您在 UGCData
中变得不确定的原因。您需要做的是 return 第一个输出处理程序中的承诺。试试这个方法:
var q = require("q");
exports.index = function(req, res,next){
var getturnto = require("getturnto")();
q().then(function(){
var deferred = q.defer();
getturnto.getUGCJson(null,function(err,re){
if(err){
console.log(err);
deferred.reject(new Error(error));
}else {
console.log(re);
deferred.resolve(re);
}
});
return deferred.promise;
})
.then(function(UGCData){
res.render('index',
{ title: 'Get UGC Content',
data:UGCData
}
);
})
.fail(function(err){
console.log(err);
next(err);
});
}
如果您将 getUGCJson
重写为 return 承诺会更好。
最终版本: 1.getturnto.js
.....
TurnToUGC.prototype.getUGCJson = function(){
*var deferred = q.defer();*
http.get(options,function(res){
....
res.on("error",function(error){
*deferred.reject(new Error(error))*;
});
res.on("end", function () {
try{
*deferred.resolve(JSON.parse(buf));*
}catch (err){
console.log(err);
}
})
}).on("error",function(er){
console.log(er);
});
*return deferred.promise;*
};
module.exports = TurnToUGC;
2.router
getturnto.getUGCJson(null).then(function(UGCData){
res.render('index',
{ title: 'Get UGC Content',
data:UGCData,
comments:UGCData.comments,
questions:UGCData.questions
}
);
})
.fail(function(err){
console.log(err);
next(err);
});
}