NodeJS获取异步返回值(回调)

时间:2014-08-20 08:07:47

标签: javascript node.js callback

我已经在互联网上阅读过关于回调的内容,但我无法理解这些内容。

我有这个功能,它运行时会记录到控制台。 但是我现在需要在另一个函数中做出这个响应,而我正在努力这样做。

var asyncJobInfo = function(jobID, next) {

    var oozie = oozieNode.createClient({ config: config });

    var command = 'job/' + jobID + '?show=info';

    console.log("running oozie command: " + command);

    oozie.get(command, function(error, response) {

    console.log("*****response would dump to console here:*****");
//  console.log(response);
    return response;
    });
};

这是我应该得到的地方: (这显然不起作用,因为它不等待响应。)

exports.getJobInfoByID = function(req, res) {

    var jobIDParam = req.params.id;
    res.send(asyncJobInfo(jobIDParam));
}

我真的很难绕过回调,而且我在这里瞎了眼。

2 个答案:

答案 0 :(得分:23)

回调无法返回值,因为他们将要返回的代码已经执行。

所以你可以做几件事。一个传递回调函数,一旦你的异步函数获得数据调用回调并传递数据。或者传递响应对象并在异步函数中使用它

传递回传

exports.getJobInfoByID = function(req, res) {
    var jobIDParam = req.params.id;
    asyncJobInfo(jobIDParam,null,function(data){
       res.send(data);
    });
}

var asyncJobInfo = function(jobID, next,callback) {
    //...
    oozie.get(command, function(error, response) {
       //do error check if ok do callback
       callback(response);
    });
};

传递响应对象

exports.getJobInfoByID = function(req, res) {
    var jobIDParam = req.params.id;
    asyncJobInfo(jobIDParam,null,res);
}

var asyncJobInfo = function(jobID, next,res) {
    //...
    oozie.get(command, function(error, response) {
       //do error check if ok do send response
       res.send(response);
    });
};

答案 1 :(得分:2)

在异步世界中,您无法返回值。无论在值准备就绪时需要做什么都应该在回调中执行。另一种选择是使用承诺。您需要es6-promise包:

var Promise = require('es6-promise').Promise;

var asyncJobInfo = function(jobID) {
  var oozie = oozieNode.createClient({config: config});
  var command = 'job/' + jobID + '?show=info';
  console.log("running oozie command: " + command);
  // Creates a new promise that wraps
  // your async code, and exposes two callbacks:
  // success, and fail.
  return new Promise(function(success, fail) {
    oozie.get(command, function(error, response) {
      if (error) {
        fail(error);
      } else {
        success(response);
      }
    });
  });
};

现在您可以使用promise并传递将在解析后运行的回调:

exports.getJobInfoByID = function(req, res) {
  asyncJobInfo(req.params.id).then(function(data) {
    res.send(data)
  }).catch(function(error) {
    console.error(error);
  });
};

以上内容可以缩短:

exports.getJobInfoByID = function(req, res) {
  asyncJobInfo(req.params.id)
    .then(res.send.bind(res))
    .catch(console.error);
};