Обратный вызов в Node.js и переменной базы данных [duplicate]

1

Я не понимаю обратные вызовы в 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;
  • 0
    @ dm03514.thanks, я просил вас не закрывать его сразу. Вы гордитесь собой? Happy ?
  • 0
    @AnnaK короткий ответ - нет. Обратный вызов выполняется в какой-то момент в будущем, который вы не можете предсказать, поэтому события, происходящие внутри его блока, доступны только в этом блоке. Если вы хотите, чтобы поведение было более привычным, вам нужно будет использовать Promises вместе с новой функцией async / await в последних версиях Node.
Показать ещё 2 комментария
Теги:

3 ответа

1
Лучший ответ

Похоже, что невозможно сделать то, что я хочу сделать в 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

1

PS. Отредактировано, чтобы следить за вопросом.

Подумайте вот так: вы попадаете в ресторан, садитесь и спрашиваете официантку за кофе. Но пока вы не замерзаете, вы двигаетесь, делаете что-то, разговариваете, поэтому, как только ваш кофе будет готов, официантка принесет его вам, и вы остановите другие дела, которые вы делаете, и выпейте свой кофе.

Таким образом, это будет примерно так:

    User.findOne({ sessionID: this.event.session.sessionId }).exec().then(data => {
    console.log(data);
}).catch(err => {
    console.log(err);
});
  • 0
    Похоже, что в Node.js невозможно сделать то, что я хочу сделать :( Что такое роутер? Это модуль nodejs? Как хороший JS-разработчик, вы могли бы посоветовать, что лучше всего решить мою проблему. Я просто хочу получить данные из базы данных и поместить их в другую переменную, которая позже будет использована в моем коде
  • 0
    Спасибо за вашу помощь, но я до сих пор не могу решить мою проблему :( Я снова плачу
Показать ещё 15 комментариев
1
// 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 но, надеюсь, это поможет вам понять обратные вызовы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню