NodeJS如何获取异步返回值(回调函数)

20

我在互联网上阅读了一些关于回调函数的内容,但是在我的情况下我仍然无法理解它们。

我有这个函数,并且在运行时会将日志记录到控制台。 然而,现在我需要在另一个函数中使用这个响应,但我很难做到。

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

我真的很难理解回调函数,现在我都看花了眼。


1
不,你不能获取返回值,最好将“req&res”传递给“asyncJobInfo”函数,并在“res.send”处执行,而不是使用“return response”。 - Mritunjay
2个回答

27

回调函数不能返回值,因为它们要返回的代码已经执行了。

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

传递回调函数

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

非常感谢,我真的需要看到一个使用我自己理解的代码示例。我知道回调函数不能有返回值,只是不理解它应该如何工作。 - Havnar

4
在异步世界中,无法直接返回值。当值准备好时,需要在回调函数中执行相关操作。另一种选择是使用Promise。你需要使用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);
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接