如何从节点中的函数返回数据?

我使用Express,并试图教自己的节点/ JavaScript的callback,我偶然发现了一些东西。

我有一个像这样的路线:

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; 

正如你所看到的,我正通过响应parameter passing给我的模块,但我宁愿传回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; 

但是,当我这样做,它是作为默认值{},但如果我像上面运行,我得到的输出,所以我知道应该有数据在那里。

如果我误解了你的问题,请告诉我。 如果你说你想从getAllInstances传回对象,那么你传入一个callback函数,并像这样从事件处理函数中调用它,

 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() ?? } }; 

这里的问题在于来自API调用的响应何时可用。 节点中的事件循环意味着代码不会阻塞,直到API回复响应。 因此需要callback来处理这个响应。 您可能希望在Express路由器响应中使用API​​响应,因此存在一系列依赖关系。

这里的一个策略是使用承诺而不是callback,这将缓解您在API调用中的asynchronous响应中遇到的一些痛苦。

在你的路线:

 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); } }; 

这可能不是剪切粘贴的工作,但看看请求承诺的例子进一步澄清。