我正在使用Express并尝试自学节点/ javascript回调,并且我偶然发现了什么。
我有一条看起来像这样的路线:
var express = require('express');
var router = express.Router();
var api = require('../api');
router.get('/',function(req, res, next){
var modulename = api.modulename;
modulename.methodname(res);
});
module.exports = router;
然后上面调用的模块如下所示:
var library = require('library');
var instances = {};
var modulename = {
getAllInstances: function(res) {
var request = new library.asyncMethod();
request.on('success', function(resp) {
instances = resp.data;
res.setHeader("Content-Type","application/json");
var returnInstances = {
id: instances[0].InstanceId,
state: {name: instances[0].State.Name, code: instances[0].State.Code}
};
res.send(returnInstances);
})
.on('error', function(resp){
console.log(resp);
})
}
};
module.exports = modulename;
正如您所看到的,我将响应参数传递到我的模块,但我宁愿传回instances
,然后在路由返回api.modulename.instances
中,就像这样:
var library = require('library');
var instances = {};
var modulename = {
getAllInstances: function() {
var request = new library.asyncMethod();
request.on('success', function(resp) {
var returnData = resp.data;
instances = {
id: returnData[0].InstanceId,
state: {name: returnData[0].State.Name, code: returnData[0].State.Code}
};
})
.on('error', function(resp){
console.log(resp);
})
.send();
}
};
module.exports = modulename;
然而,当我这样做时,它会以默认值{}的形式出现,但如果我按上面那样运行它,我会得到输出,所以我知道那里应该有数据。
答案 0 :(得分:1)
如果我误解了你的问题,请告诉我。如果你想要传回来自getAllInstances
的对象,那么你传入一个回调并从事件处理程序中调用它 -
router.get('/',function(req, res, next){
var modulename = api.modulename;
modulename.getAllInstances(res, function(err, instances){
if(err){ ... }
else{
res.send(instances); //or however you want to use instances
}
});
});
并在getInstances
var modulename = {
getAllInstances: function(res, cb) {
var request = new library.asyncMethod();
request.on('success', function(resp) {
instances = resp.data;
var returnInstances = {
id: instances[0].InstanceId,
state: {name: instances[0].State.Name, code: instances[0].State.Code}
};
cb(null, instances);
})
.on('error', function(err){
cb(err, null));
});
//.send(); not sure what this is it seems to be request.send() ??
}
};
答案 1 :(得分:0)
这里的问题在于API调用的响应何时可用。 Node中的事件循环意味着在API回复响应之前代码不会阻塞。因此,当响应可用时,需要回调来处理该响应。您可能希望在Express路由器响应中使用API响应,因此存在一系列依赖关系。
这里的一个策略是使用promises而不是回调,它可以缓解您在API调用中遇到异步响应时遇到的一些痛苦。
在您的路线中:
router.get('/',function(req, res, next){
var instances = [];
// The function below could be refactored into a library to minimise controller code.
var resolver = function (response) {
var data = JSON.parse(response);
instances.push({
name: data[0].State.Name,
code: data[0].State.Code
});
res.render('instances'. {instances : instances});
};
modulename.methodname(resolver);
});
在你的模块中:
var rp = require('request-promise'); // Also see q-io/http as an alternate lib.
var modulename = {
methodname: function (resolver) {
rp('http://the-inter.net')
.then(resolver)
.catch(console.error);
}
};
这可能不会削减粘贴效果,但请查看request-promise examples以进一步说明。