Я не понимаю обратные вызовы в nodejs.
Мне нужно получить номер подкаста из базы данных и использовать его в моем коде
Я получаю прямо сейчас из console.log
[Function: index]
Есть ли какое-либо решение в node.js для получения переменной из базы данных и повторного использования ее позже в коде?
var index = function( callback ) {
var podcast = 0;
User.findOne({ sessionID: this.event.session.sessionId }, function(err, user) {
if (err ||!user){
}
else {
console.log(user);
podcast = user.podcast;
}
});
callback( podcast );
};
index();
var callback = function(data) {
return data;
}
var iUseMyAnywhere = callback;
Похоже, что невозможно сделать то, что я хочу сделать в Node.js
Это вполне возможно. Только вам нужно использовать асинхронные API, что делает его неловким.
Есть ли какое-либо решение в node.js для получения переменной из базы данных и повторного использования ее позже в коде?
Не совсем. Когда вы подключаетесь к базе данных -or, кстати, делайте что-нибудь асинхронно, например, извлекая что-то через http или чтение из disc-, вы не можете назначить эту вещь прямо:
var myUserFromDb = User.find('john doe', function(err, res){...}); //this will fail
Потому что эта функция вы передаете, поскольку второй параметр будет выполняться когда-нибудь в будущем. User.find()
сам не возвращает пользователя.
К сожалению, вы не можете просто получить пользователя в user
var и передать его другому модулю -let, например, подкаст module-.
Однако предположим, что у вас есть модуль user.js, который предоставляет метод withUser
чем aks для базы данных для пользователя, а затем вызывает предоставленную функцию с пользователем, когда вызов db разрешен.
И пусть у вас есть файл/модуль getPodcast
методом getPodcast
который нужен пользователю.
getPodcast
не может просто запрашивать пользователя user.js. Однако он может запросить функцию, которая будет работать с пользователем, переданным как параметр:
user.js
function withUser(callback){
User.find({_id: 1}, (err, user)=> {
callback(user);
})
}
podcast.js
function getPodcast(){
withUser( function(user){
//now we really have the user inside podcast.js, and we can work with it.
//Sadly, that will surely involve more asynchronous api's, which is painful.
})
}
Теперь getPodcast
будет иметь доступ к пользователю внутри своего обратного вызова параметров.
Есть ли более простой метод, чем обратный вызов?
Да, вы должны прочитать о обещаниях. При использовании обещаний вещи -a немного less- болезненны. Обещание api будет работать так:
user.js
function getUser(id){
//let say we return a promise that wraps the 'User.find' database request
}
podcast.js
getUser(userId).then(user => getPodcast(user)).then(podcastResult => ...)
Это лучше не выглядит. Однако, когда вы работаете с обещаниями api, вы можете начать использовать async/wait.
podcast.js
async function getPodcast(userId){
const user = await User.getUser(uesrId);
const otherAsyncThing = await ...someAsyncApiCall;
doAnythingWithUser(user); //this line won't execute until user is resolved, even if there aren't callbacks involved :-D
}
Заключительное, непонятное слово совета: при работе с node.js убедитесь, что вы понимаете, как работают callback api и async, прежде чем писать тонну кода. В противном случае вы получите действительно связанный и хрупкий код, где объекты пройдут через горы обратных вызовов, а код нечитабелен и неуязвим: -D
PS. Отредактировано, чтобы следить за вопросом.
Подумайте вот так: вы попадаете в ресторан, садитесь и спрашиваете официантку за кофе. Но пока вы не замерзаете, вы двигаетесь, делаете что-то, разговариваете, поэтому, как только ваш кофе будет готов, официантка принесет его вам, и вы остановите другие дела, которые вы делаете, и выпейте свой кофе.
Таким образом, это будет примерно так:
User.findOne({ sessionID: this.event.session.sessionId }).exec().then(data => {
console.log(data);
}).catch(err => {
console.log(err);
});
// getPodcast accepts a function as an arg
const getPodcast = callback => {
// Some async operation happens with its own callback.
User.findOne({ sessionID: this.event.session.sessionId }, (err, user) => {
if (err || !user) {
// Log on failure
console.error('Failed to retrieve podcast.')
}
else {
// here, callback is console.log and receives user.podcast as an arg
callback(user.podcast)
}
})
}
// The function is invoked and passed a function as a callback, in this case console.log
getPodcast(console.log)
Я не уверен, как вы связываете this.event.session.sessionId
но, надеюсь, это поможет вам понять обратные вызовы.
Happy
?