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

时间:2015-09-24 08:29:25

标签: javascript node.js

我正在使用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;

然而,当我这样做时,它会以默认值{}的形式出现,但如果我按上面那样运行它,我会得到输出,所以我知道那里应该有数据。

2 个答案:

答案 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以进一步说明。