NodeJS получает возвращаемое значение async (обратный вызов)
Я читал в Интернете о обратных вызовах, но я просто не могу понять их в моем случае.
У меня есть эта функция, и она записывается в консоль при ее запуске.
Однако мне теперь нужен этот ответ в другой функции, и я изо всех сил стараюсь это сделать.
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
Обратные вызовы не могут вернуть значение, поскольку код, который они будут возвращать, уже выполнен.
Итак, вы можете сделать пару вещей. Один передаёт функцию обратного вызова, и как только ваша функция async получает вызов данных обратного вызова и передает данные. Или передать объект ответа и использовать его в вашей асинхронной функции
Передача обратного вызова
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);
});
};
Ответ 2
В асинхронном мире вы не можете возвращать значения. Независимо от того, что необходимо сделать, когда значение будет готово, должно выполняться внутри обратного вызова. Другой вариант - использование promises. Вам понадобится пакет 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);
}
});
});
};
Теперь вы можете использовать обещание и передавать обратные вызовы, которые будут выполняться после его разрешения:
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);
};